13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.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 ES2.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *							 Utilities to glshared?
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fUniformApiTests.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 "deString.h"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp"
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 gles3
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_MAT2X3,
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT2X4,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT3X2,
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT3,
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT3X4,
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT4X2,
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT4X3,
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT4,
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC2,
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC3,
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC4,
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT,
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT_VEC2,
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT_VEC3,
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT_VEC4,
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL,
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC2,
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC3,
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC4,
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_SAMPLER_2D,
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_SAMPLER_CUBE
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note We don't test all sampler types here.
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getGLInt (const glw::Functions& funcs, const deUint32 name)
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int val = -1;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	funcs.getIntegerv(name, &val);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return val;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Vec4 vec4FromPtr (const float* const ptr)
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4 result;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = ptr[i];
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string beforeLast (const string& str, const char c)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str.substr(0, str.find_last_of(c));
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void fillWithColor (const tcu::PixelBufferAccess& access, const tcu::Vec4& color)
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int z = 0; z < access.getDepth(); z++)
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < access.getHeight(); y++)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < access.getWidth(); x++)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		access.setPixel(color, x, y, z);
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getSamplerNumLookupDimensions (const glu::DataType type)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D:
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D:
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D:
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 2;
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_3D:
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_3D:
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_3D:
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_SHADOW:
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY:
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE:
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE:
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE:
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 3;
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE_SHADOW:
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 4;
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline glu::DataType getSamplerLookupReturnType (const glu::DataType type)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D:
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE:
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY:
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_3D:
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT_VEC4;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D:
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE:
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_3D:
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_UINT_VEC4;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D:
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE:
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_3D:
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INT_VEC4;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_SHADOW:
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE_SHADOW:
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_LAST;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<glu::DataType T>
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool dataTypeEquals (const glu::DataType t)
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return t == T;
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int N>
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool dataTypeIsMatrixWithNRows (const glu::DataType t)
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::isDataTypeMatrix(t) && glu::getDataTypeMatrixNumRows(t) == N;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool typeContainsMatchingBasicType (const glu::VarType& type, const dataTypePredicate predicate)
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return predicate(type.getBasicType());
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return typeContainsMatchingBasicType(type.getElementType(), predicate);
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate))
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getDistinctSamplerTypes (vector<glu::DataType>& dst, const glu::VarType& type)
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType basicType = type.getBasicType();
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicType) && std::find(dst.begin(), dst.end(), basicType) == dst.end())
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.push_back(basicType);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getDistinctSamplerTypes(dst, type.getElementType());
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getDistinctSamplerTypes(dst, structType.getMember(i).getType());
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumSamplersInType (const glu::VarType& type)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return glu::isDataTypeSampler(type.getBasicType()) ? 1 : 0;
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return getNumSamplersInType(type.getElementType()) * type.getArraySize();
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int sum = 0;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sum += getNumSamplersInType(structType.getMember(i).getType());
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sum;
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::VarType generateRandomType (const int maxDepth, int& curStructIdx, vector<const StructType*>& structTypesDst, Random& rnd)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isStruct		= maxDepth > 0 && rnd.getFloat() < 0.2f;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool isArray		= rnd.getFloat() < 0.3f;
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isStruct)
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			numMembers = rnd.getInt(1, 5);
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const	structType = new StructType(("structType" + de::toString(curStructIdx++)).c_str());
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numMembers; i++)
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember(("m" + de::toString(i)).c_str(), generateRandomType(maxDepth-1, curStructIdx, structTypesDst, rnd));
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structTypesDst.push_back(structType);
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return isArray ? glu::VarType(glu::VarType(structType), rnd.getInt(1, 5)) : glu::VarType(structType);
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		basicType = (glu::DataType)s_testDataTypes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testDataTypes)-1)];
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision	precision = glu::isDataTypeBoolOrBVec(basicType) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return isArray ? glu::VarType(glu::VarType(basicType, precision), rnd.getInt(1, 5)) : glu::VarType(basicType, precision);
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VarValue
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType type;
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	union
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float		floatV[4*4]; // At most mat4. \note Matrices here are column-major.
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt32		intV[4];
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	uintV[4];
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool		boolV[4];
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		struct
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		unit;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			union
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		floatV[4];
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deInt32		intV[4];
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	uintV[4];
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			} fillColor;
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} samplerV;
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} val;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum CaseShaderType
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_VERTEX = 0,
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_FRAGMENT,
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_BOTH,
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_LAST
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Uniform
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			name;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::VarType	type;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Uniform (const char* const name_, const glu::VarType& type_) : name(name_), type(type_) {}
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// A set of uniforms, along with related struct types.
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformCollection
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getNumUniforms		(void) const					{ return (int)m_uniforms.size();	}
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getNumStructTypes	(void) const					{ return (int)m_structTypes.size();	}
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Uniform&			getUniform			(const int ndx)					{ return m_uniforms[ndx];			}
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Uniform&		getUniform			(const int ndx) const			{ return m_uniforms[ndx];			}
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const StructType*	getStructType		(const int ndx) const			{ return m_structTypes[ndx];		}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				addUniform			(const Uniform& uniform)		{ m_uniforms.push_back(uniform);	}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				addStructType		(const StructType* const type)	{ m_structTypes.push_back(type);	}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollection	(void) {}
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	~UniformCollection	(void)
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_structTypes.size(); i++)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete m_structTypes[i];
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one.
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note receiver takes ownership of the struct types.
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void moveContents (UniformCollection& receiver)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			receiver.addUniform(m_uniforms[i]);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_uniforms.clear();
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_structTypes.size(); i++)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			receiver.addStructType(m_structTypes[i]);
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_structTypes.clear();
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool containsMatchingBasicType (const dataTypePredicate predicate) const
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (typeContainsMatchingBasicType(m_uniforms[i].type, predicate))
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::DataType> getSamplerTypes (void) const
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<glu::DataType> samplerTypes;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getDistinctSamplerTypes(samplerTypes, m_uniforms[i].type);
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return samplerTypes;
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool containsSeveralSamplerTypes (void) const
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return getSamplerTypes().size() > 1;
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getNumSamplers (void) const
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int sum = 0;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sum += getNumSamplersInType(m_uniforms[i].type);
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sum;
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basic (const glu::DataType type, const char* const nameSuffix = "")
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(type, prec)));
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basicArray (const glu::DataType type, const char* const nameSuffix = "")
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(glu::VarType(type, prec), 3)));
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basicStruct (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec0	= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec1	= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const structType = new StructType((string("structType") + nameSuffix).c_str());
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m0", glu::VarType(type0, prec0));
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m1", glu::VarType(type1, prec1));
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (containsArrays)
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember("m2", glu::VarType(glu::VarType(type0, prec0), 3));
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember("m3", glu::VarType(glu::VarType(type1, prec1), 3));
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(structType);
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* structInArray (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const res = basicStruct(type0, type1, containsArrays, nameSuffix);
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->getUniform(0).type = glu::VarType(res->getUniform(0).type, 3);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* nestedArraysStructs (const glu::DataType type0, const glu::DataType type1, const char* const nameSuffix = "")
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const res		= new UniformCollection;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision prec0			= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision prec1			= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const structType		= new StructType((string("structType") + nameSuffix).c_str());
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const subStructType		= new StructType((string("subStructType") + nameSuffix).c_str());
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const subSubStructType	= new StructType((string("subSubStructType") + nameSuffix).c_str());
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subSubStructType->addMember("mss0", glu::VarType(type0, prec0));
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subSubStructType->addMember("mss1", glu::VarType(type1, prec1));
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms0", glu::VarType(type1, prec1));
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms1", glu::VarType(glu::VarType(type0, prec0), 2));
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms2", glu::VarType(glu::VarType(subSubStructType), 2));
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m0", glu::VarType(type0, prec0));
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m1", glu::VarType(subStructType));
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m2", glu::VarType(type1, prec1));
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(subSubStructType);
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(subStructType);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(structType);
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleBasic (const char* const nameSuffix = "")
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types[]	= { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_UINT_VEC4, glu::TYPE_FLOAT_MAT3, glu::TYPE_BOOL_VEC2 };
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = basic(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleBasicArray (const char* const nameSuffix = "")
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types[]	= { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_BOOL_VEC2 };
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = basicArray(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleNestedArraysStructs (const char* const nameSuffix = "")
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types0[]	= { glu::TYPE_FLOAT,		glu::TYPE_INT,		glu::TYPE_BOOL_VEC4 };
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types1[]	= { glu::TYPE_FLOAT_VEC4,	glu::TYPE_INT_VEC4,	glu::TYPE_BOOL };
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res			= new UniformCollection;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types0) == DE_LENGTH_OF_ARRAY(types1));
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types0); i++)
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = nestedArraysStructs(types0[i], types1[i], ("_" + de::toString(i) + nameSuffix).c_str());
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* random (const deUint32 seed)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Random						rnd			(seed);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					numUniforms	= rnd.getInt(1, 5);
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int							structIdx	= 0;
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res			= new UniformCollection;
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numUniforms; i++)
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<const StructType*>	structTypes;
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Uniform						uniform(("u_var" + de::toString(i)).c_str(), glu::VarType());
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Discard uniforms that would cause number of samplers to exceed MAX_NUM_SAMPLER_UNIFORMS.
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			do
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int j = 0; j < (int)structTypes.size(); j++)
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					delete structTypes[j];
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				structTypes.clear();
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				uniform.type = (("u_var" + de::toString(i)).c_str(), generateRandomType(3, structIdx, structTypes, rnd));
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			} while (res->getNumSamplers() + getNumSamplersInType(uniform.type) > MAX_NUM_SAMPLER_UNIFORMS);
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res->addUniform(uniform);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int j = 0; j < (int)structTypes.size(); j++)
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				res->addStructType(structTypes[j]);
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Copying these would be cumbersome, since deep-copying both m_uniforms and m_structTypes
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// would mean that we'd need to update pointers from uniforms to point to the new structTypes.
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// When the same UniformCollection is needed in several places, a SharedPtr is used instead.
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCollection	(const UniformCollection&); // Not allowed.
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollection&			operator=			(const UniformCollection&); // Not allowed.
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Uniform>				m_uniforms;
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<const StructType*>	m_structTypes;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; // anonymous
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getSamplerFillValue (const VarValue& sampler)
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeSampler(sampler.type));
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue result;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = getSamplerLookupReturnType(sampler.type);
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (result.type)
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_VEC4:
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.val.floatV[i] = sampler.val.samplerV.fillColor.floatV[i];
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_VEC4:
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.val.uintV[i] = sampler.val.samplerV.fillColor.uintV[i];
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_VEC4:
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.val.intV[i] = sampler.val.samplerV.fillColor.intV[i];
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT:
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.floatV[0] = sampler.val.samplerV.fillColor.floatV[0];
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getSamplerUnitValue (const VarValue& sampler)
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeSampler(sampler.type));
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue result;
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = glu::TYPE_INT;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.val.intV[0] = sampler.val.samplerV.unit;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::DataType getDataTypeTransposedMatrix (const glu::DataType original)
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::getDataTypeMatrix(glu::getDataTypeMatrixNumRows(original), glu::getDataTypeMatrixNumColumns(original));
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getTransposeMatrix (const VarValue& original)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeMatrix(original.type));
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	rows = glu::getDataTypeMatrixNumRows(original.type);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	cols = glu::getDataTypeMatrixNumColumns(original.type);
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue	result;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = getDataTypeTransposedMatrix(original.type);
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < rows; i++)
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int j = 0; j < cols; j++)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.floatV[i*cols + j] = original.val.floatV[j*rows + i];
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string shaderVarValueStr (const VarValue& value)
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numElems = glu::getDataTypeScalarSize(value.type);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << glu::getDataTypeName(value.type) << "(";
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numElems; i++)
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i > 0)
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << ", ";
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::floatToString(value.val.floatV[i], 2);
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec((value.type)))
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.intV[i]);
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec((value.type)))
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.uintV[i]) << "u";
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec((value.type)))
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << (value.val.boolV[i] ? "true" : "false");
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler((value.type)))
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << shaderVarValueStr(getSamplerFillValue(value));
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << ")";
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string apiVarValueStr (const VarValue& value)
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numElems = glu::getDataTypeScalarSize(value.type);
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << "(";
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numElems; i++)
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i > 0)
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << ", ";
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::floatToString(value.val.floatV[i], 2);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec((value.type)))
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.intV[i]);
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec((value.type)))
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.uintV[i]);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec((value.type)))
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << (value.val.boolV[i] ? "true" : "false");
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler((value.type)))
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << value.val.samplerV.unit;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << ")";
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko 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. */)
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numElems = glu::getDataTypeScalarSize(type);
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue	result;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = type;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((samplerUnit >= 0) == (glu::isDataTypeSampler(type)));
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(type))
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.intV[i] = rnd.getInt(-10, 10);
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeUintOrUVec(type))
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.uintV[i] = (deUint32)rnd.getInt(0, 10);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(type))
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.boolV[i] = rnd.getBool();
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(type))
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		texResultType		= getSamplerLookupReturnType(type);
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		texResultScalarType	= glu::getDataTypeScalarType(texResultType);
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				texResultNumDims	= glu::getDataTypeScalarSize(texResultType);
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.samplerV.unit = samplerUnit;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < texResultNumDims; i++)
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (texResultScalarType)
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT:	result.val.samplerV.fillColor.floatV[i]		= rnd.getFloat(0.0f, 1.0f);		break;
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_INT:		result.val.samplerV.fillColor.intV[i]		= rnd.getInt(-10, 10);			break;
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_UINT:	result.val.samplerV.fillColor.uintV[i]		= (deUint32)rnd.getInt(0, 10);	break;
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue generateZeroVarValue (const glu::DataType type)
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numElems = glu::getDataTypeScalarSize(type);
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue	result;
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = type;
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.floatV[i] = 0.0f;
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(type))
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.intV[i] = 0;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeUintOrUVec(type))
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.uintV[i] = 0u;
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(type))
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.boolV[i] = false;
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(type))
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		texResultType		= getSamplerLookupReturnType(type);
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		texResultScalarType	= glu::getDataTypeScalarType(texResultType);
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				texResultNumDims	= glu::getDataTypeScalarSize(texResultType);
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.samplerV.unit = 0;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < texResultNumDims; i++)
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (texResultScalarType)
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT:	result.val.samplerV.fillColor.floatV[i]		= 0.12f * (float)i;	break;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_INT:		result.val.samplerV.fillColor.intV[i]		= -2 + i;			break;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_UINT:	result.val.samplerV.fillColor.uintV[i]		= 4 + i;			break;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool apiVarValueEquals (const VarValue& a, const VarValue& b)
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		size			= glu::getDataTypeScalarSize(a.type);
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		floatThreshold	= 0.05f;
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(a.type == b.type);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(a.type) || glu::isDataTypeMatrix(a.type))
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (de::abs(a.val.floatV[i] - b.val.floatV[i]) >= floatThreshold)
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(a.type))
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.intV[i] != b.val.intV[i])
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeUintOrUVec(a.type))
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.uintV[i] != b.val.uintV[i])
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(a.type))
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.boolV[i] != b.val.boolV[i])
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(a.type))
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (a.val.samplerV.unit != b.val.samplerV.unit)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getRandomBoolRepresentation (const VarValue& boolValue, const glu::DataType targetScalarType, Random& rnd)
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeBoolOrBVec(boolValue.type));
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				size		= glu::getDataTypeScalarSize(boolValue.type);
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		targetType	= size == 1 ? targetScalarType : glu::getDataTypeVector(targetScalarType, size);
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue				result;
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = targetType;
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (targetScalarType)
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT:
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.intV[i] = rnd.getInt(-10, 10);
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (result.val.intV[i] == 0)
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						result.val.intV[i] = 1;
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.intV[i] = 0;
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT:
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.uintV[i] = rnd.getInt(1, 10);
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.uintV[i] = 0;
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT:
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (result.val.floatV[i] == 0.0f)
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						result.val.floatV[i] = 1.0f;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.floatV[i] = 0;
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getCaseShaderTypeName (const CaseShaderType type)
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_VERTEX:		return "vertex";
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_FRAGMENT:	return "fragment";
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_BOTH:		return "both";
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic CaseShaderType randomCaseShaderType (const deUint32 seed)
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (CaseShaderType)Random(seed).getInt(0, CASESHADERTYPE_LAST-1);
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformCase : public TestCase, protected glu::CallLogWrapper
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Feature
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices.
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX	= 1<<0,
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9173c827367444ee418f129b2c238299f49d3264554Jarkko 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.
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMFUNC_VALUE				= 1<<1,
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major.
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_MATRIXMODE_ROWMAJOR				= 1<<2,
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ARRAYASSIGN: how basic-type arrays are assigned with glUniform*(). If none given, assign each element of an array separately.
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYASSIGN_FULL				= 1<<3, //!< Assign all elements of an array with one glUniform*().
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO		= 1<<4, //!< Assign two elements per one glUniform*().
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9273c827367444ee418f129b2c238299f49d3264554Jarkko 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).
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMUSAGE_EVERY_OTHER		= 1<<5,
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float.
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_BOOLEANAPITYPE_INT				= 1<<6,
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_BOOLEANAPITYPE_UINT				= 1<<7,
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// UNIFORMVALUE_ZERO: use zero-valued uniforms. If not given, use random uniform values.
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMVALUE_ZERO				= 1<<8,
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko 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.
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX	= 1<<9
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection);
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 features);
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, deUint32 seed); // \note Randomizes caseType, uniformCollection and features.
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~UniformCase	(void);
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				init			(void);
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				deinit			(void);
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate			(void);
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniform
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue		finalValue;	//!< The value we ultimately want to set for this uniform.
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9603c827367444ee418f129b2c238299f49d3264554Jarkko 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.
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				elemNdx;	//!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				rootSize;	//!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniform (const char* const		name_,
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const glu::DataType	type_,
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const bool			isUsedInShader_,
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const VarValue&		finalValue_,
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char* const		rootName_	= DE_NULL,
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				elemNdx_	= -1,
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				rootSize_	= 1)
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  : name			(name_)
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , type			(type_)
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , isUsedInShader	(isUsedInShader_)
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , finalValue		(finalValue_)
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootName		(rootName_ == DE_NULL ? name_ : rootName_)
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , elemNdx			(elemNdx_)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootSize		(rootSize_)
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 {
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 }
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static vector<BasicUniform>::const_iterator findWithName (const vector<BasicUniform>& vec, const char* const name)
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<BasicUniform>::const_iterator it = vec.begin(); it != vec.end(); it++)
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (it->name == name)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return it;
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vec.end();
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniformsiv().
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniformReportRef
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
9963c827367444ee418f129b2c238299f49d3264554Jarkko 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.
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				minSize;
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				maxSize;
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const int minS, const int maxS, const glu::DataType type_, const bool used)
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(minS), maxSize(maxS), type(type_), isUsedInShader(used) { DE_ASSERT(minSize <= maxSize); }
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const glu::DataType type_, const bool used)
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(1), maxSize(1), type(type_), isUsedInShader(used) {}
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Info that is actually reported by glGetActiveUniform() or glGetActiveUniformsiv().
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniformReportGL
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				nameLength; // \note Whether this includes the null byte depends on whether it was queried with glGetActiveUniform() or glGetActiveUniformsiv().
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				size;
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				index;
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportGL (const char* const name_, const int nameLength_, const int size_, const glu::DataType type_, const int index_)
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), nameLength(nameLength_), size(size_), type(type_), index(index_) {}
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static vector<BasicUniformReportGL>::const_iterator findWithName (const vector<BasicUniformReportGL>& vec, const char* const name)
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<BasicUniformReportGL>::const_iterator it = vec.begin(); it != vec.end(); it++)
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (it->name == name)
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return it;
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vec.end();
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Query info with glGetActiveUniform() and check validity.
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getActiveUniforms						(vector<BasicUniformReportGL>& dst, const vector<BasicUniformReportRef>& ref, deUint32 programGL);
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Query info with glGetUniformIndices() + glGetActiveUniformsiv() and check validity.
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getActiveUniformsiv						(vector<BasicUniformReportGL>& dst, const vector<BasicUniformReportRef>& ref, deUint32 programGL);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare infos returned by glGetActiveUniform() and glGetUniformIndices() + glGetActiveUniformsiv().
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						uniformVsUniformsivComparison			(const vector<BasicUniformReportGL>& uniformsResult, const vector<BasicUniformReportGL>& uniformsivResult);
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get uniform values with glGetUniform*() and put to valuesDst. Uniforms that get -1 from glGetUniformLocation() get glu::TYPE_INVALID.
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getUniforms								(vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, deUint32 programGL);
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check that every uniform has the default (zero) value.
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						checkUniformDefaultValues				(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assign the basicUniforms[].finalValue values for uniforms. \note rnd parameter is for booleans (true can be any nonzero value).
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						assignUniforms							(const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd);
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare the uniform values given in values (obtained with glGetUniform*()) with the basicUniform.finalValue values.
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						compareUniformValues					(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render and check that all pixels are white (i.e. all uniform comparisons passed).
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						renderTest								(const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd);
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool				test									(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd) = 0;
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32								m_features;
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const SharedPtr<const UniformCollection>	m_uniformCollection;
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static deUint32				randomFeatures							(deUint32 seed);
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generates the basic uniforms, based on the uniform with name varName and type varType, in the same manner as are expected
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// to be returned by glGetActiveUniform(), e.g. generates a name like var[0] for arrays, and recursively generates struct member names.
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						generateBasicUniforms					(vector<BasicUniform>&				basicUniformsDst,
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 vector<BasicUniformReportRef>&		basicUniformReportsDst,
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const glu::VarType&				varType,
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*						varName,
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 bool								isParentActive,
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 int&								samplerUnitCounter,
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 Random&							rnd) const;
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformDefinitions					(std::ostringstream& dst) const;
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformCompareExpr					(std::ostringstream& dst, const BasicUniform& uniform) const;
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformComparisons					(std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* variableName) const;
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateVertexSource					(const vector<BasicUniform>& basicUniforms) const;
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateFragmentSource					(const vector<BasicUniform>& basicUniforms) const;
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupTexture							(const VarValue& value);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseShaderType						m_caseShaderType;
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::Texture2D*>						m_textures2d;
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::TextureCube*>					m_texturesCube;
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>							m_filledTextureUnits;
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10833c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 UniformCase::randomFeatures (const deUint32 seed)
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 arrayUsageChoices[]		= { 0, FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX										};
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformFuncChoices[]		= { 0, FEATURE_UNIFORMFUNC_VALUE												};
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 matrixModeChoices[]		= { 0, FEATURE_MATRIXMODE_ROWMAJOR												};
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 arrayAssignChoices[]		= { 0, FEATURE_ARRAYASSIGN_FULL,			FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	};
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformUsageChoices[]		= { 0, FEATURE_UNIFORMUSAGE_EVERY_OTHER											};
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 booleanApiTypeChoices[]	= { 0, FEATURE_BOOLEANAPITYPE_INT,			FEATURE_BOOLEANAPITYPE_UINT			};
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 uniformValueChoices[]		= { 0, FEATURE_UNIFORMVALUE_ZERO												};
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random rnd(seed);
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 result = 0;
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define ARRAY_CHOICE(ARR) (ARR[rnd.getInt(0, DE_LENGTH_OF_ARRAY(ARR)-1)])
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(arrayUsageChoices);
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformFuncChoices);
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(matrixModeChoices);
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(arrayAssignChoices);
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformUsageChoices);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(booleanApiTypeChoices);
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result |= ARRAY_CHOICE(uniformValueChoices);
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef ARRAY_CHOICE
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 features)
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(features)
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(uniformCollection)
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(caseShaderType)
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection)
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(0)
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(uniformCollection)
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(caseShaderType)
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* name, const char* description, const deUint32 seed)
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(randomFeatures(seed))
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(UniformCollection::random(seed))
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(randomCaseShaderType(seed))
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::init (void)
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	funcs						= m_context.getRenderContext().getFunctions();
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numSamplerUniforms			= m_uniformCollection->getNumSamplers();
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsRequired		= m_caseShaderType != CASESHADERTYPE_FRAGMENT ? numSamplerUniforms : 0;
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsRequired	= m_caseShaderType != CASESHADERTYPE_VERTEX ? numSamplerUniforms : 0;
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsRequired	= vertexTexUnitsRequired + fragmentTexUnitsRequired;
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsSupported		= getGLInt(funcs, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsSupported	= getGLInt(funcs, GL_MAX_TEXTURE_IMAGE_UNITS);
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsSupported	= getGLInt(funcs, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numSamplerUniforms <= MAX_NUM_SAMPLER_UNIFORMS);
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexTexUnitsRequired > vertexTexUnitsSupported)
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(vertexTexUnitsRequired) + " vertex texture units required, " + de::toString(vertexTexUnitsSupported) + " supported");
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(fragmentTexUnitsRequired) + " fragment texture units required, " + de::toString(fragmentTexUnitsSupported) + " supported");
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (combinedTexUnitsRequired > combinedTexUnitsSupported)
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(combinedTexUnitsRequired) + " combined texture units required, " + de::toString(combinedTexUnitsSupported) + " supported");
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::deinit (void)
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_textures2d.size(); i++)
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures2d[i];
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures2d.clear();
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_texturesCube.size(); i++)
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_texturesCube[i];
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texturesCube.clear();
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_filledTextureUnits.clear();
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::~UniformCase (void)
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCase::deinit();
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11823c827367444ee418f129b2c238299f49d3264554Jarkko 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
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType())
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isActive	= isParentActive && (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true);
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= varType.getBasicType();
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue			value		= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(type)
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: glu::isDataTypeSampler(type)				? generateRandomVarValue(type, rnd, samplerUnitCounter++)
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: generateRandomVarValue(varType.getBasicType(), rnd);
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformsDst.push_back(BasicUniform(varName, varType.getBasicType(), isActive, value));
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformReportsDst.push_back(BasicUniformReportRef(varName, varType.getBasicType(), isActive));
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isArrayType())
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		size			= varType.getArraySize();
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	arrayRootName	= string("") + varName + "[0]";
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<bool>	isElemActive;
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++)
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	indexedName		= string("") + varName + "[" + de::toString(elemNdx) + "]";
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		isCurElemActive	= isParentActive																						&&
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER			? basicUniformsDst.size() % 2 == 0	: true)	&&
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX		? elemNdx == size/2					: true);
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isElemActive.push_back(isCurElemActive);
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (varType.getElementType().isBasicType())
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::DataType	elemBasicType	= varType.getElementType().getBasicType();
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const VarValue		value			= m_features & FEATURE_UNIFORMVALUE_ZERO	? generateZeroVarValue(elemBasicType)
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: glu::isDataTypeSampler(elemBasicType)		? generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++)
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: generateRandomVarValue(elemBasicType, rnd);
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformsDst.push_back(BasicUniform(indexedName.c_str(), elemBasicType, isCurElemActive, value, arrayRootName.c_str(), elemNdx, size));
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName.c_str(), isCurElemActive, samplerUnitCounter, rnd);
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (varType.getElementType().isBasicType())
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int minSize;
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize-1]; minSize--);
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicUniformReportsDst.push_back(BasicUniformReportRef(arrayRootName.c_str(), minSize, size, varType.getElementType().getBasicType(), isParentActive && minSize > 0));
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(varType.isStructType());
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *varType.getStructPtr();
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::StructMember&	member			= structType.getMember(i);
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string				memberFullName	= string("") + varName + "." + member.getName();
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName.c_str(), isParentActive, samplerUnitCounter, rnd);
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformDefinitions (std::ostringstream& dst) const
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumStructTypes(); i++)
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << glu::declare(m_uniformCollection->getStructType(i)) << ";\n";
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "uniform " << glu::declare(m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str()) << ";\n";
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << "\n";
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const struct
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataTypePredicate	requiringTypes[2];
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*			definition;
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} compareFuncs[] =
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12653c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																		},
12663c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"														},
12673c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"								},
12683c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"		},
12693c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"													},
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT2X3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat2x3   (mediump mat2x3 a, mediump mat2x3 b){ return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1]); }"													},
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT2X4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat2x4   (mediump mat2x4 a, mediump mat2x4 b){ return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1]); }"													},
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT3X2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat3x2   (mediump mat3x2 a, mediump mat3x2 b){ return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2]); }"							},
12733c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"							},
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT3X4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat3x4   (mediump mat3x4 a, mediump mat3x4 b){ return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2]); }"							},
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT4X2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat4x2   (mediump mat4x2 a, mediump mat4x2 b){ return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2])*compare_vec2(a[3], b[3]); }"	},
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT4X3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat4x3   (mediump mat4x3 a, mediump mat4x3 b){ return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2])*compare_vec3(a[3], b[3]); }"	},
12773c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"	},
12783c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
12793c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
12803c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
12813c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_UINT>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uint     (mediump uint a, mediump uint b)    { return a == b ? 1.0 : 0.0; }"																					},
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_UINT_VEC2>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uvec2    (mediump uvec2 a, mediump uvec2 b)  { return a == b ? 1.0 : 0.0; }"																					},
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_UINT_VEC3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uvec3    (mediump uvec3 a, mediump uvec3 b)  { return a == b ? 1.0 : 0.0; }"																					},
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_UINT_VEC4>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_uvec4    (mediump uvec4 a, mediump uvec4 b)  { return a == b ? 1.0 : 0.0; }"																					},
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_BOOL>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bool     (bool a, bool b)                    { return a == b ? 1.0 : 0.0; }"																					},
12873c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
12883c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
12893c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					}
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<glu::DataType> samplerTypes = m_uniformCollection->getSamplerTypes();
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compFuncNdx = 0; compFuncNdx < DE_LENGTH_OF_ARRAY(compareFuncs); compFuncNdx++)
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const dataTypePredicate		(&typeReq)[2]			= compareFuncs[compFuncNdx].requiringTypes;
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool						containsTypeSampler		= false;
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)samplerTypes.size(); i++)
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (glu::isDataTypeSampler(samplerTypes[i]))
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const glu::DataType retType = getSamplerLookupReturnType(samplerTypes[i]);
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (typeReq[0](retType) || typeReq[1](retType))
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						containsTypeSampler = true;
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (containsTypeSampler || m_uniformCollection->containsMatchingBasicType(typeReq[0]) || m_uniformCollection->containsMatchingBasicType(typeReq[1]))
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst << compareFuncs[compFuncNdx].definition << "\n";
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformCompareExpr (std::ostringstream& dst, const BasicUniform& uniform) const
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeSampler(uniform.type))
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_" << glu::getDataTypeName(getSamplerLookupReturnType(uniform.type)) << "(texture(" << uniform.name << ", vec" << getSamplerNumLookupDimensions(uniform.type) << "(0.0))";
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_" << glu::getDataTypeName(uniform.type) << "(" << uniform.name;
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << ", " << shaderVarValueStr(uniform.finalValue) << ")";
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformComparisons (std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* const variableName) const
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform& unif = basicUniforms[i];
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unif.isUsedInShader)
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t" << variableName << " *= ";
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeUniformCompareExpr(dst, basicUniforms[i]);
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << ";\n";
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t// UNUSED: " << basicUniforms[i].name << "\n";
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateVertexSource (const vector<BasicUniform>& basicUniforms) const
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX || m_caseShaderType == CASESHADERTYPE_BOTH;
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "#version 300 es\n"
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "in highp vec4 a_position;\n"
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "out mediump float v_vtxOut;\n"
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	gl_Position = a_position;\n"
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	v_vtxOut = 1.0;\n";
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "v_vtxOut");
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "}\n";
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateFragmentSource (const vector<BasicUniform>& basicUniforms) const
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isFragmentCase = m_caseShaderType == CASESHADERTYPE_FRAGMENT || m_caseShaderType == CASESHADERTYPE_BOTH;
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "#version 300 es\n"
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "in mediump float v_vtxOut;\n"
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n"
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	mediump float result = v_vtxOut;\n";
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "result");
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "	dEQP_FragColor = vec4(result, result, result, 1.0);\n"
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "}\n";
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::setupTexture (const VarValue& value)
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note No handling for samplers other than 2D or cube.
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(false);
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(getSamplerLookupReturnType(value.type) == glu::TYPE_FLOAT_VEC4);
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						width			= 32;
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						height			= 32;
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4					color			= vec4FromPtr(&value.val.samplerV.fillColor.floatV[0]);
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (value.type == glu::TYPE_SAMPLER_2D)
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Texture2D* texture		= new glu::Texture2D(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width, height);
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Texture2D& refTexture	= texture->getRefTexture();
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures2d.push_back(texture);
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		refTexture.allocLevel(0);
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fillWithColor(refTexture.getLevel(0), color);
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (value.type == glu::TYPE_SAMPLER_CUBE)
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(width == height);
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::TextureCube* texture		= new glu::TextureCube(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width);
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureCube& refTexture	= texture->getRefTexture();
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texturesCube.push_back(texture);
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refTexture.allocLevel((tcu::CubeFace)face, 0);
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fillWithColor(refTexture.getLevelFace(0, (tcu::CubeFace)face), color);
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getActiveUniforms (vector<BasicUniformReportGL>& basicUniformReportsDst, const vector<BasicUniformReportRef>& basicUniformReportsRef, const deUint32 programGL)
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log						= m_testCtx.getLog();
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint				numActiveUniforms		= 0;
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint				uniformMaxNameLength	= 0;
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<char>		nameBuffer;
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				success					= true;
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORMS, &numActiveUniforms));
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "// Number of active uniforms reported: " << numActiveUniforms << TestLog::EndMessage;
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetProgramiv(programGL, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxNameLength));
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "// Maximum uniform name length reported: " << uniformMaxNameLength << TestLog::EndMessage;
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	nameBuffer.resize(uniformMaxNameLength);
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < numActiveUniforms; unifNdx++)
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLsizei					reportedNameLength	= 0;
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint					reportedSize		= -1;
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum					reportedTypeGL		= GL_NONE;
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGetActiveUniform(programGL, (GLuint)unifNdx, (GLsizei)uniformMaxNameLength, &reportedNameLength, &reportedSize, &reportedTypeGL, &nameBuffer[0]));
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		reportedType		= glu::getDataTypeFromGLType(reportedTypeGL);
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			reportedNameStr		(&nameBuffer[0]);
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Got name = " << reportedNameStr << ", name length = " << reportedNameLength << ", size = " << reportedSize << ", type = " << glu::getDataTypeName(reportedType) << TestLog::EndMessage;
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((GLsizei)reportedNameStr.length() != reportedNameLength)
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: wrong name length reported, should be " << reportedNameStr.length() << TestLog::EndMessage;
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!deStringBeginsWith(reportedNameStr.c_str(), "gl_")) // Ignore built-in uniforms.
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int referenceNdx;
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (referenceNdx = 0; referenceNdx < (int)basicUniformReportsRef.size(); referenceNdx++)
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (basicUniformReportsRef[referenceNdx].name == reportedNameStr)
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (referenceNdx >= (int)basicUniformReportsRef.size())
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: invalid non-built-in uniform name reported" << TestLog::EndMessage;
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const BasicUniformReportRef& reference = basicUniformReportsRef[referenceNdx];
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.type != glu::TYPE_LAST);
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize <= reference.maxSize);
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (BasicUniformReportGL::findWithName(basicUniformReportsDst, reportedNameStr.c_str()) != basicUniformReportsDst.end())
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: same uniform name reported twice" << TestLog::EndMessage;
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformReportsDst.push_back(BasicUniformReportGL(reportedNameStr.c_str(), reportedNameLength, reportedSize, reportedType, unifNdx));
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedType != reference.type)
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: wrong type reported, should be " << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "// FAILURE: wrong size reported, should be "
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< (reference.minSize == reference.maxSize ? de::toString(reference.minSize) : "in the range [" + de::toString(reference.minSize) + ", " + de::toString(reference.maxSize) + "]")
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniformReportRef& expected = basicUniformReportsRef[i];
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (expected.isUsedInShader && BasicUniformReportGL::findWithName(basicUniformReportsDst, expected.name.c_str()) == basicUniformReportsDst.end())
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: uniform with name " << expected.name << " was not reported by GL" << TestLog::EndMessage;
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getActiveUniformsiv (vector<BasicUniformReportGL>& basicUniformReportsDst, const vector<BasicUniformReportRef>& basicUniformReportsRef, const deUint32 programGL)
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<string>			queryNames		(basicUniformReportsRef.size());
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<const char*>		queryNamesC		(basicUniformReportsRef.size());
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<GLuint>			uniformIndices	(basicUniformReportsRef.size());
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>		validUniformIndices; // This shall have the same contents, and in same order, as uniformIndices, but with GL_INVALID_INDEX entries removed.
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					success			= true;
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniformReportsRef.size(); i++)
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string& name = basicUniformReportsRef[i].name;
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		queryNames[i]	= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && name[name.size()-1] == ']' ? beforeLast(name, '[') : name;
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		queryNamesC[i]	= queryNames[i].c_str();
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glGetUniformIndices(programGL, (GLsizei)basicUniformReportsRef.size(), &queryNamesC[0], &uniformIndices[0]));
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)uniformIndices.size(); i++)
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniformIndices[i] != GL_INVALID_INDEX)
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			validUniformIndices.push_back(uniformIndices[i]);
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (basicUniformReportsRef[i].isUsedInShader)
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: uniform with name " << basicUniformReportsRef[i].name << " received GL_INVALID_INDEX" << TestLog::EndMessage;
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!validUniformIndices.empty())
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<GLint> uniformNameLengthBuf	(validUniformIndices.size());
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<GLint> uniformSizeBuf		(validUniformIndices.size());
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<GLint> uniformTypeBuf		(validUniformIndices.size());
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0], GL_UNIFORM_NAME_LENGTH,	&uniformNameLengthBuf[0]));
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0], GL_UNIFORM_SIZE,			&uniformSizeBuf[0]));
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glGetActiveUniformsiv(programGL, (GLsizei)validUniformIndices.size(), &validUniformIndices[0], GL_UNIFORM_TYPE,			&uniformTypeBuf[0]));
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int validNdx = -1; // Keeps the corresponding index to validUniformIndices while unifNdx is the index to uniformIndices.
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int unifNdx = 0; unifNdx < (int)uniformIndices.size(); unifNdx++)
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (uniformIndices[unifNdx] == GL_INVALID_INDEX)
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				validNdx++;
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const BasicUniformReportRef&	reference			= basicUniformReportsRef[unifNdx];
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int						reportedIndex		= validUniformIndices[validNdx];
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int						reportedNameLength	= (int)uniformNameLengthBuf[validNdx];
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int						reportedSize		= (int)uniformSizeBuf[validNdx];
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::DataType				reportedType		= glu::getDataTypeFromGLType((deUint32)uniformTypeBuf[validNdx]);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_CHECK_MSG(reportedType != glu::TYPE_LAST, "Invalid uniform type");
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< "// Got name length = " << reportedNameLength
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< ", size = " << reportedSize
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< ", type = " << glu::getDataTypeName(reportedType)
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< " for the uniform at index " << reportedIndex << " (" << reference.name << ")"
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					<< TestLog::EndMessage;
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.type != glu::TYPE_LAST);
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader));
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(reference.minSize <= reference.maxSize);
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformReportsDst.push_back(BasicUniformReportGL(reference.name.c_str(), reportedNameLength, reportedSize, reportedType, reportedIndex));
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedNameLength != (int)reference.name.length() + 1)
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: wrong name length reported, should be " << reference.name.length() + 1 << TestLog::EndMessage;
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedType != reference.type)
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message << "// FAILURE: wrong type reported, should be " << glu::getDataTypeName(reference.type) << TestLog::EndMessage;
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (reportedSize < reference.minSize || reportedSize > reference.maxSize)
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << TestLog::Message
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< "// FAILURE: wrong size reported, should be "
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< (reference.minSize == reference.maxSize ? de::toString(reference.minSize) : "in the range [" + de::toString(reference.minSize) + ", " + de::toString(reference.maxSize) + "]")
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< TestLog::EndMessage;
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					success = false;
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::uniformVsUniformsivComparison (const vector<BasicUniformReportGL>& uniformResults, const vector<BasicUniformReportGL>& uniformsivResults)
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int uniformResultNdx = 0; uniformResultNdx < (int)uniformResults.size(); uniformResultNdx++)
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniformReportGL&							uniformResult		= uniformResults[uniformResultNdx];
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string&										uniformName			= uniformResult.name;
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<BasicUniformReportGL>::const_iterator	uniformsivResultIt	= BasicUniformReportGL::findWithName(uniformsivResults, uniformName.c_str());
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniformsivResultIt != uniformsivResults.end())
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const BasicUniformReportGL& uniformsivResult = *uniformsivResultIt;
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Checking uniform " << uniformName << TestLog::EndMessage;
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniformResult.index != uniformsivResult.index)
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetUniformIndices() gave different indices for uniform " << uniformName << TestLog::EndMessage;
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniformResult.nameLength + 1 != uniformsivResult.nameLength)
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave incompatible name lengths for uniform " << uniformName << TestLog::EndMessage;
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniformResult.size != uniformsivResult.size)
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave different sizes for uniform " << uniformName << TestLog::EndMessage;
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniformResult.type != uniformsivResult.type)
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: glGetActiveUniform() and glGetActiveUniformsiv() gave different types for uniform " << uniformName << TestLog::EndMessage;
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: uniform " << uniformName << " was reported active by glGetActiveUniform() but not by glGetUniformIndices()" << TestLog::EndMessage;
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int uniformsivResultNdx = 0; uniformsivResultNdx < (int)uniformsivResults.size(); uniformsivResultNdx++)
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniformReportGL&							uniformsivResult	= uniformsivResults[uniformsivResultNdx];
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string&										uniformsivName		= uniformsivResult.name;
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<BasicUniformReportGL>::const_iterator	uniformsResultIt	= BasicUniformReportGL::findWithName(uniformsivResults, uniformsivName.c_str());
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uniformsResultIt == uniformsivResults.end())
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: uniform " << uniformsivName << " was reported active by glGetUniformIndices() but not by glGetActiveUniform()" << TestLog::EndMessage;
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getUniforms (vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, const deUint32 programGL)
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName	= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				location	= glGetUniformLocation(programGL, queryName.c_str());
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				size		= glu::getDataTypeScalarSize(uniform.type);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue				value;
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemset(&value, 0xcd, sizeof(value)); // Initialize to known garbage.
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location == -1)
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.type = glu::TYPE_INVALID;
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesDst.push_back(value);
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniform.isUsedInShader)
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: " << uniform.name << " was used in shader, but has location -1" << TestLog::EndMessage;
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		value.type = uniform.type;
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLint) == sizeof(value.val.intV[0]));
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(value.val.uintV[0]));
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(value.val.floatV[0]));
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(uniform.type))
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec(uniform.type))
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec(uniform.type))
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_features & FEATURE_BOOLEANAPITYPE_INT)
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.intV[i] != 0;
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_features & FEATURE_BOOLEANAPITYPE_UINT)
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.uintV[i] != 0;
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // Default: use float.
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.floatV[i] != 0.0f;
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(uniform.type))
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLint unit = -1;
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &unit));
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.val.samplerV.unit = unit;
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		valuesDst.push_back(value);
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Got " << uniform.name << " value " << apiVarValueStr(value) << TestLog::EndMessage;
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::checkUniformDefaultValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(values.size() == basicUniforms.size());
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue&			unifValue	= values[unifNdx];
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				valSize		= glu::getDataTypeScalarSize(uniform.type);
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define CHECK_UNIFORM(VAR_VALUE_MEMBER, ZERO)																								\
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	do																																		\
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																																		\
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < valSize; i++)																									\
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{																																	\
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (unifValue.val.VAR_VALUE_MEMBER[i] != ZERO)																					\
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{																																\
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;	\
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;																											\
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}																																\
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}																																	\
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} while (false)
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(floatV, 0.0f);
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(uniform.type))
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(intV, 0);
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec(uniform.type))
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(uintV, 0);
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec(uniform.type))
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			CHECK_UNIFORM(boolV, false);
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(uniform.type))
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (unifValue.val.samplerV.unit != 0)
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: uniform " << uniform.name << " has non-zero initial value" << TestLog::EndMessage;
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef CHECK_UNIFORM
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::assignUniforms (const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd)
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				transpose		= (m_features & FEATURE_MATRIXMODE_ROWMAJOR) != 0;
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLboolean			transposeGL		= transpose ? GL_TRUE : GL_FALSE;
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		boolApiType		= m_features & FEATURE_BOOLEANAPITYPE_INT	? glu::TYPE_INT
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: m_features & FEATURE_BOOLEANAPITYPE_UINT	? glu::TYPE_UINT
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											:											  glu::TYPE_FLOAT;
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform				= basicUniforms[unifNdx];
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isArrayMember		= uniform.elemNdx >= 0;
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName			= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numValuesToAssign	= !isArrayMember									? 1
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_FULL				? (uniform.elemNdx == 0			? uniform.rootSize	: 0)
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	? (uniform.elemNdx % 2 == 0		? 2					: 0)
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: /* Default: assign array elements separately */	  1;
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign >= 0);
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign == 1 || isArrayMember);
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numValuesToAssign == 0)
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Uniform " << uniform.name << " is covered by another glUniform*v() call to the same array" << TestLog::EndMessage;
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			location			= glGetUniformLocation(programGL, queryName.c_str());
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			typeSize			= glu::getDataTypeScalarSize(uniform.type);
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			assignByValue		= m_features & FEATURE_UNIFORMFUNC_VALUE && !glu::isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue>	valuesToAssign;
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numValuesToAssign; i++)
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	curName = isArrayMember ? beforeLast(uniform.rootName, '[') + "[" + de::toString(uniform.elemNdx+i) + "]" : uniform.name;
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VarValue		unifValue;
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isArrayMember)
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const vector<BasicUniform>::const_iterator elemUnif = BasicUniform::findWithName(basicUniforms, curName.c_str());
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (elemUnif == basicUniforms.end())
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = elemUnif->finalValue;
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = uniform.finalValue;
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const VarValue apiValue = glu::isDataTypeBoolOrBVec(unifValue.type)	? getRandomBoolRepresentation(unifValue, boolApiType, rnd)
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: glu::isDataTypeSampler(unifValue.type)	? getSamplerUnitValue(unifValue)
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: unifValue;
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesToAssign.push_back(glu::isDataTypeMatrix(apiValue.type) && transpose ? getTransposeMatrix(apiValue) : apiValue);
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isDataTypeBoolOrBVec(uniform.type))
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Using type " << glu::getDataTypeName(boolApiType) << " to set boolean value " << apiVarValueStr(unifValue) << " for " << curName << TestLog::EndMessage;
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (glu::isDataTypeSampler(uniform.type))
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Texture for the sampler uniform " << curName << " will be filled with color " << apiVarValueStr(getSamplerFillValue(uniform.finalValue)) << TestLog::EndMessage;
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!valuesToAssign.empty());
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(valuesToAssign[0].type))
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float* const ptr = &valuesToAssign[0].val.floatV[0];
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1f(location, ptr[0]));							break;
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2f(location, ptr[0], ptr[1]));					break;
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3f(location, ptr[0], ptr[1], ptr[2]));			break;
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4f(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<float> buffer(valuesToAssign.size() * typeSize);
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4fv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeMatrix(valuesToAssign[0].type))
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!assignByValue);
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<float> buffer(valuesToAssign.size() * typeSize);
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)buffer.size(); i++)
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (uniform.type)
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2:		GLU_CHECK_CALL(glUniformMatrix2fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3:		GLU_CHECK_CALL(glUniformMatrix3fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4:		GLU_CHECK_CALL(glUniformMatrix4fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2X3:	GLU_CHECK_CALL(glUniformMatrix2x3fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2X4:	GLU_CHECK_CALL(glUniformMatrix2x4fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3X2:	GLU_CHECK_CALL(glUniformMatrix3x2fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3X4:	GLU_CHECK_CALL(glUniformMatrix3x4fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4X2:	GLU_CHECK_CALL(glUniformMatrix4x2fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4X3:	GLU_CHECK_CALL(glUniformMatrix4x3fv	(location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(valuesToAssign[0].type))
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deInt32* const ptr = &valuesToAssign[0].val.intV[0];
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1i(location, ptr[0]));							break;
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2i(location, ptr[0], ptr[1]));					break;
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3i(location, ptr[0], ptr[1], ptr[2]));			break;
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4i(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<deInt32> buffer(valuesToAssign.size() * typeSize);
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLint) == sizeof(buffer[0]));
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4iv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec(valuesToAssign[0].type))
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32* const ptr = &valuesToAssign[0].val.uintV[0];
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1ui(location, ptr[0]));							break;
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2ui(location, ptr[0], ptr[1]));					break;
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3ui(location, ptr[0], ptr[1], ptr[2]));			break;
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4ui(location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<deUint32> buffer(valuesToAssign.size() * typeSize);
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(buffer[0]));
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glUniform1uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glUniform2uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glUniform3uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glUniform4uiv(location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(valuesToAssign[0].type))
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glUniform1i(location, uniform.finalValue.val.samplerV.unit));
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLint unit = uniform.finalValue.val.samplerV.unit;
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glUniform1iv(location, (GLsizei)valuesToAssign.size(), &unit));
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::compareUniformValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue&			unifValue	= values[unifNdx];
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!apiVarValueEquals(unifValue, uniform.finalValue))
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: value obtained with glGetUniform*() for uniform " << uniform.name << " differs from value set with glUniform*()" << TestLog::EndMessage;
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::renderTest (const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd)
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log				= m_testCtx.getLog();
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportW		= de::min(renderTarget.getWidth(),	MAX_RENDER_WIDTH);
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportH		= de::min(renderTarget.getHeight(),	MAX_RENDER_HEIGHT);
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportX		= rnd.getInt(0, renderTarget.getWidth()		- viewportW);
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportY		= rnd.getInt(0, renderTarget.getHeight()	- viewportH);
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedImg		(viewportW, viewportH);
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assert that no two samplers of different types have the same texture unit - this is an error in GL.
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type))
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int j = 0; j < i; j++)
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (glu::isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit);
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type) && std::find(m_filledTextureUnits.begin(), m_filledTextureUnits.end(), basicUniforms[i].finalValue.val.samplerV.unit) == m_filledTextureUnits.end())
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Filling texture at unit " << apiVarValueStr(basicUniforms[i].finalValue) << " with color " << shaderVarValueStr(basicUniforms[i].finalValue) << TestLog::EndMessage;
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setupTexture(basicUniforms[i].finalValue);
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportW, viewportH));
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const float position[] =
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, -1.0f, 0.0f, 1.0f,
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, +1.0f, 0.0f, 1.0f,
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, -1.0f, 0.0f, 1.0f,
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, +1.0f, 0.0f, 1.0f
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int posLoc = glGetAttribLocation(program.getProgram(), "a_position");
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glEnableVertexAttribArray(posLoc);
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_SHORT, &indices[0]));
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numFailedPixels = 0;
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < renderedImg.getWidth(); x++)
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (renderedImg.getPixel(x, y) != tcu::RGBA::white)
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += 1;
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels > 0)
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-white pixels" << TestLog::EndMessage;
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: got all-white pixels (all uniforms have correct values)" << TestLog::EndMessage;
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::IterateResult UniformCase::iterate (void)
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random							rnd				(deStringHash(getName()) ^ (deUint32)m_context.getTestContext().getCommandLine().getBaseSeed());
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log				= m_testCtx.getLog();
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniform>			basicUniforms;
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportRef>	basicUniformReportsRef;
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int samplerUnitCounter = 0;
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniforms, basicUniformReportsRef, m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str(), true, samplerUnitCounter, rnd);
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					vertexSource	= generateVertexSource(basicUniforms);
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					fragmentSource	= generateFragmentSource(basicUniforms);
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderProgram				program			(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource));
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << program;
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program.isOk())
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glUseProgram(program.getProgram()));
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool success = test(basicUniforms, basicUniformReportsRef, program, rnd);
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							success ? "Passed"				: "Failed");
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformInfoQueryCase : public UniformCase
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_UNIFORM = 0,			//!< Check info returned by glGetActiveUniform().
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_INDICES_UNIFORMSIV,	//!< Check info returned by glGetUniformIndices() + glGetActiveUniformsiv().
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_CONSISTENCY,			//!< Query info with both above methods, and check consistency.
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						UniformInfoQueryCase	(Context& context, const char* name, const char* description, CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, CaseType caseType, deUint32 additionalFeatures = 0);
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCaseTypeName			(CaseType caseType);
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCaseTypeDescription	(CaseType caseType);
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType		m_caseType;
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformInfoQueryCase::getCaseTypeName (const CaseType caseType)
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (caseType)
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_UNIFORM:				return "active_uniform";
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_INDICES_UNIFORMSIV:	return "indices_active_uniformsiv";
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_CONSISTENCY:			return "consistency";
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformInfoQueryCase::getCaseTypeDescription (const CaseType caseType)
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (caseType)
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_UNIFORM:				return "Test glGetActiveUniform()";
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_INDICES_UNIFORMSIV:	return "Test glGetUniformIndices() along with glGetActiveUniformsiv()";
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_CONSISTENCY:			return "Check consistency between results from glGetActiveUniform() and glGetUniformIndices() + glGetActiveUniformsiv()";
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformInfoQueryCase::UniformInfoQueryCase (Context& context, const char* const name, const char* const description, const CaseShaderType shaderType, const SharedPtr<const UniformCollection>& uniformCollection, const CaseType caseType, const deUint32 additionalFeatures)
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase	(context, name, description, shaderType, uniformCollection, additionalFeatures)
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseType	(caseType)
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformInfoQueryCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(basicUniforms);
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(rnd);
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32					programGL	= program.getProgram();
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log			= m_testCtx.getLog();
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportGL>	basicUniformReportsUniform;
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportGL>	basicUniformReportsUniformsiv;
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_caseType == CASETYPE_UNIFORM || m_caseType == CASETYPE_CONSISTENCY)
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool success = false;
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = getActiveUniforms(basicUniformReportsUniform, basicUniformReportsRef, programGL);
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_caseType == CASETYPE_UNIFORM)
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(m_caseType == CASETYPE_CONSISTENCY);
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Note: this is a consistency case, so ignoring above failure(s)" << TestLog::EndMessage;
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_caseType == CASETYPE_INDICES_UNIFORMSIV || m_caseType == CASETYPE_CONSISTENCY)
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool success = false;
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "InfoGetActiveUniformsiv", "Uniform information queries with glGetUniformIndices() and glGetActiveUniformsiv()");
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = getActiveUniformsiv(basicUniformReportsUniformsiv, basicUniformReportsRef, programGL);
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_caseType == CASETYPE_INDICES_UNIFORMSIV)
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(m_caseType == CASETYPE_CONSISTENCY);
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Note: this is a consistency case, so ignoring above failure(s)" << TestLog::EndMessage;
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_caseType == CASETYPE_CONSISTENCY)
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool success = false;
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "CompareUniformVsUniformsiv", "Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()");
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = uniformVsUniformsivComparison(basicUniformReportsUniform, basicUniformReportsUniformsiv);
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformValueCase : public UniformCase
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum ValueToCheck
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_INITIAL = 0,		//!< Verify the initial values of the uniforms (i.e. check that they're zero).
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_ASSIGNED,			//!< Assign values to uniforms with glUniform*(), and check those.
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALUETOCHECK_LAST
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CheckMethod
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_GET_UNIFORM = 0,	//!< Check values with glGetUniform*().
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_RENDER,				//!< Check values by rendering with the value-checking shader.
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_LAST
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum AssignMethod
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_POINTER = 0,
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_VALUE,
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_LAST
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						UniformValueCase			(Context&									context,
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								name,
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								description,
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CaseShaderType								shaderType,
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const SharedPtr<const UniformCollection>&	uniformCollection,
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ValueToCheck								valueToCheck,
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CheckMethod								checkMethod,
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 AssignMethod								assignMethod,
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 deUint32									additionalFeatures = 0);
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test						(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getValueToCheckName			(ValueToCheck valueToCheck);
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getValueToCheckDescription	(ValueToCheck valueToCheck);
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodName			(CheckMethod checkMethod);
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodDescription	(CheckMethod checkMethod);
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodName			(AssignMethod checkMethod);
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodDescription	(AssignMethod checkMethod);
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ValueToCheck	m_valueToCheck;
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CheckMethod	m_checkMethod;
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getValueToCheckName (const ValueToCheck valueToCheck)
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (valueToCheck)
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_INITIAL:	return "initial";
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_ASSIGNED:	return "assigned";
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);	return DE_NULL;
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getValueToCheckDescription (const ValueToCheck valueToCheck)
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (valueToCheck)
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_INITIAL:	return "Check initial uniform values (zeros)";
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VALUETOCHECK_ASSIGNED:	return "Check assigned uniform values";
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);	return DE_NULL;
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getCheckMethodName (const CheckMethod checkMethod)
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "get_uniform";
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "render";
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getCheckMethodDescription (const CheckMethod checkMethod)
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "Verify values with glGetUniform*()";
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "Verify values by rendering";
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getAssignMethodName (const AssignMethod assignMethod)
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "by_pointer";
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "by_value";
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformValueCase::getAssignMethodDescription (const AssignMethod assignMethod)
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "Assign values by-pointer";
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "Assign values by-value";
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformValueCase::UniformValueCase (Context&									context,
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const							name,
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const							description,
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const CaseShaderType						shaderType,
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const SharedPtr<const UniformCollection>&	uniformCollection,
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const ValueToCheck							valueToCheck,
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const CheckMethod							checkMethod,
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const AssignMethod							assignMethod,
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const deUint32								additionalFeatures)
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase		(context, name, description, shaderType, uniformCollection,
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 (valueToCheck == VALUETOCHECK_INITIAL ? FEATURE_UNIFORMVALUE_ZERO : 0) | (assignMethod == ASSIGNMETHOD_VALUE ? FEATURE_UNIFORMFUNC_VALUE : 0) | additionalFeatures)
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_valueToCheck	(valueToCheck)
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_checkMethod		(checkMethod)
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!(assignMethod == ASSIGNMETHOD_LAST && valueToCheck == VALUETOCHECK_ASSIGNED));
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformValueCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(basicUniformReportsRef);
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	programGL	= program.getProgram();
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log			= m_testCtx.getLog();
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		assignUniforms(basicUniforms, programGL, rnd);
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_checkMethod == CHECKMETHOD_GET_UNIFORM)
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> values;
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "GetUniforms", "Uniform value query");
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = getUniforms(values, basicUniforms, program.getProgram());
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_valueToCheck == VALUETOCHECK_ASSIGNED)
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values");
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = compareUniformValues(values, basicUniforms);
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(m_valueToCheck == VALUETOCHECK_INITIAL);
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "ValueCheck", "Verify that the uniforms have correct initial values (zeros)");
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = checkUniformDefaultValues(values, basicUniforms);
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_checkMethod == CHECKMETHOD_RENDER);
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "RenderTest", "Render test");
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = renderTest(basicUniforms, program, rnd);
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass RandomUniformCase : public UniformCase
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						RandomUniformCase		(Context& m_context, const char* name, const char* description, deUint32 seed);
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test					(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRandomUniformCase::RandomUniformCase (Context& context, const char* const name, const char* const description, const deUint32 seed)
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase (context, name, description, seed ^ (deUint32)context.getTestContext().getCommandLine().getBaseSeed())
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool RandomUniformCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Different sampler types may not be bound to same unit when rendering.
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		renderingPossible						= (m_features & FEATURE_UNIFORMVALUE_ZERO) == 0 || !m_uniformCollection->containsSeveralSamplerTypes();
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			performGetActiveUniforms				= rnd.getBool();
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performGetActiveUniformsiv				= rnd.getBool();
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performUniformVsUniformsivComparison	= performGetActiveUniforms && performGetActiveUniformsiv && rnd.getBool();
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performGetUniforms						= rnd.getBool();
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performCheckUniformDefaultValues		= performGetUniforms && rnd.getBool();
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performAssignUniforms					= rnd.getBool();
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performCompareUniformValues				= performGetUniforms && performAssignUniforms && rnd.getBool();
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		performRenderTest						= renderingPossible && performAssignUniforms && rnd.getBool();
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	programGL								= program.getProgram();
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log										= m_testCtx.getLog();
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!(performGetActiveUniforms || performGetActiveUniformsiv || performUniformVsUniformsivComparison || performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms || performCompareUniformValues || performRenderTest))
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		performGetActiveUniforms = true; // Do something at least.
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PERFORM_AND_CHECK(CALL, SECTION_NAME, SECTION_DESCRIPTION)						\
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	do																					\
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{																					\
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, (SECTION_NAME), (SECTION_DESCRIPTION));		\
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = (CALL);													\
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)																	\
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;																\
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} while (false)
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<BasicUniformReportGL> reportsUniform;
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<BasicUniformReportGL> reportsUniformsiv;
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performGetActiveUniforms)
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getActiveUniforms(reportsUniform, basicUniformReportsRef, programGL), "InfoGetActiveUniform", "Uniform information queries with glGetActiveUniform()");
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performGetActiveUniformsiv)
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getActiveUniformsiv(reportsUniformsiv, basicUniformReportsRef, programGL), "InfoGetActiveUniformsiv", "Uniform information queries with glGetIndices() and glGetActiveUniformsiv()");
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performUniformVsUniformsivComparison)
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(uniformVsUniformsivComparison(reportsUniform, reportsUniformsiv), "CompareUniformVsUniformsiv", "Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()");
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> uniformDefaultValues;
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performGetUniforms)
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getUniforms(uniformDefaultValues, basicUniforms, programGL), "GetUniformDefaults", "Uniform default value query");
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performCheckUniformDefaultValues)
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(checkUniformDefaultValues(uniformDefaultValues, basicUniforms), "DefaultValueCheck", "Verify that the uniforms have correct initial values (zeros)");
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> uniformValues;
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performAssignUniforms)
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			assignUniforms(basicUniforms, programGL, rnd);
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (performCompareUniformValues)
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(getUniforms(uniformValues, basicUniforms, programGL), "GetUniforms", "Uniform value query");
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PERFORM_AND_CHECK(compareUniformValues(uniformValues, basicUniforms), "ValueCheck", "Verify that the reported values match the assigned values");
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (performRenderTest)
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PERFORM_AND_CHECK(renderTest(basicUniforms, program, rnd), "RenderTest", "Render test");
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PERFORM_AND_CHECK
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformApiTests::UniformApiTests (Context& context)
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "uniform_api", "Uniform API Tests")
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformApiTests::~UniformApiTests (void)
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note Although this is only used in UniformApiTest::init, it needs to be defined here as it's used as a template argument.
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct UniformCollectionCase
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string								namePrefix;
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SharedPtr<const UniformCollection>	uniformCollection;
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollectionCase (const char* const name, const UniformCollection* uniformCollection_)
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: namePrefix			(name ? name + string("_") : "")
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, uniformCollection		(uniformCollection_)
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformApiTests::init (void)
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate sets of UniformCollections that are used by several cases.
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC = 0,
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_ARRAY,
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_STRUCT,
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY,
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT,
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS,
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC,
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY,
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS,
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_LAST
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct UniformCollectionGroup
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string							name;
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<UniformCollectionCase>	cases;
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} defaultUniformCollections[UNIFORMCOLLECTIONS_LAST];
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].name							= "basic";
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].name						= "basic_array";
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].name						= "basic_struct";
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].name					= "struct_in_array";
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].name					= "array_in_struct";
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].name			= "nested_structs_arrays";
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].name					= "multiple_basic";
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].name				= "multiple_basic_array";
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].name	= "multiple_nested_structs_arrays";
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_testDataTypes); dataTypeNdx++)
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		dataType	= s_testDataTypes[dataTypeNdx];
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const		typeName	= glu::getDataTypeName(dataType);
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basic(dataType)));
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)													||
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(glu::isDataTypeVector(dataType) && glu::getDataTypeScalarSize(dataType) == 4)	||
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4												||
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basicArray(dataType)));
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)		||
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4	||
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::DataType		secondDataType	= glu::isDataTypeScalar(dataType)	? glu::getDataTypeVector(dataType, 4)
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_FLOAT_MAT4	? glu::TYPE_FLOAT_MAT2
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_SAMPLER_2D	? glu::TYPE_SAMPLER_CUBE
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: glu::TYPE_LAST;
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(secondDataType != glu::TYPE_LAST);
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		secondTypeName	= glu::getDataTypeName(secondDataType);
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string			name			= string("") + typeName + "_" + secondTypeName;
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].cases.push_back			(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, false)));
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, true)));
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::structInArray(dataType, secondDataType, false)));
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(name.c_str(), UniformCollection::nestedArraysStructs(dataType, secondDataType)));
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].cases.push_back					(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasic()));
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].cases.push_back				(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasicArray()));
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(DE_NULL, UniformCollection::multipleNestedArraysStructs()));
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Info-query cases (check info returned by e.g. glGetActiveUniforms()).
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const infoQueryGroup = new TestCaseGroup(m_context, "info_query", "Test uniform info querying functions");
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(infoQueryGroup);
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseTypeI = 0; caseTypeI < (int)UniformInfoQueryCase::CASETYPE_LAST; caseTypeI++)
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformInfoQueryCase::CaseType	caseType		= (UniformInfoQueryCase::CaseType)caseTypeI;
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const					caseTypeGroup	= new TestCaseGroup(m_context, UniformInfoQueryCase::getCaseTypeName(caseType), UniformInfoQueryCase::getCaseTypeDescription(caseType));
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			infoQueryGroup->addChild(caseTypeGroup);
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int numArrayFirstElemNameCases = caseType == UniformInfoQueryCase::CASETYPE_INDICES_UNIFORMSIV && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1;
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++)
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionGroup&	collectionGroup			= defaultUniformCollections[collectionGroupNdx];
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string					collectionGroupName		= collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const			collectionTestGroup		= new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					caseTypeGroup->addChild(collectionTestGroup);
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionCase& collectionCase = collectionGroup.cases[collectionNdx];
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string								name				= collectionCase.namePrefix + getCaseShaderTypeName((CaseShaderType)shaderType);
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							collectionTestGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection, (UniformInfoQueryCase::CaseType)caseType,
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX));
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Info-querying cases when unused uniforms are present.
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				caseTypeGroup->addChild(unusedUniformsGroup);
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string								collName			= collectionCase.namePrefix;
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						unusedUniformsGroup->addChild(new UniformInfoQueryCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection, (UniformInfoQueryCase::CaseType)caseType,
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			   UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER | UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX));
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cases testing uniform values.
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const valueGroup = new TestCaseGroup(m_context, "value", "Uniform value tests");
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(valueGroup);
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering.
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const initialValuesGroup = new TestCaseGroup(m_context,
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_INITIAL),
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_INITIAL));
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueGroup->addChild(initialValuesGroup);
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				initialValuesGroup->addChild(checkMethodGroup);
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[collectionGroupNdx];
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					checkMethodGroup->addChild(collectionTestGroup);
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string								collName			= collectionCase.namePrefix;
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																						  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int									numBoolVariations	= varyBoolApiType ? 3 : 1;
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (checkMethod == UniformValueCase::CHECKMETHOD_RENDER && uniformCollection->containsSeveralSamplerTypes())
27743c827367444ee418f129b2c238299f49d3264554Jarkko 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.
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const deUint32		booleanTypeFeat	= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: 0;
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char* const	booleanTypeName	= booleanTypeI == 1 ? "int"
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: booleanTypeI == 2 ? "uint"
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: "float";
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string		nameWithApiType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string name = nameWithApiType + getCaseShaderTypeName((CaseShaderType)shaderType);
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   UniformValueCase::VALUETOCHECK_INITIAL, checkMethod, UniformValueCase::ASSIGNMETHOD_LAST, booleanTypeFeat));
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering.
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const assignedValuesGroup = new TestCaseGroup(m_context,
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckName(UniformValueCase::VALUETOCHECK_ASSIGNED),
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		UniformValueCase::getValueToCheckDescription(UniformValueCase::VALUETOCHECK_ASSIGNED));
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valueGroup->addChild(assignedValuesGroup);
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int assignMethodI = 0; assignMethodI < (int)UniformValueCase::ASSIGNMETHOD_LAST; assignMethodI++)
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformValueCase::AssignMethod	assignMethod		= (UniformValueCase::AssignMethod)assignMethodI;
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const					assignMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getAssignMethodName(assignMethod), UniformValueCase::getAssignMethodDescription(assignMethod));
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				assignedValuesGroup->addChild(assignMethodGroup);
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int checkMethodI = 0; checkMethodI < (int)UniformValueCase::CHECKMETHOD_LAST; checkMethodI++)
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformValueCase::CheckMethod		checkMethod			= (UniformValueCase::CheckMethod)checkMethodI;
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformValueCase::getCheckMethodName(checkMethod), UniformValueCase::getCheckMethodDescription(checkMethod));
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					assignMethodGroup->addChild(checkMethodGroup);
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int numArrayFirstElemNameCases = checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1;
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++)
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const UniformCollectionGroup&	collectionGroup			= defaultUniformCollections[collectionGroupNdx];
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string					collectionGroupName		= collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							TestCaseGroup* const			collectionTestGroup		= new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							checkMethodGroup->addChild(collectionTestGroup);
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string								collName			= collectionCase.namePrefix;
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									varyBoolApiType		= checkMethod == UniformValueCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																								  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int									numBoolVariations	= varyBoolApiType ? 3 : 1;
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									containsMatrices	= uniformCollection->containsMatchingBasicType(glu::isDataTypeMatrix);
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const bool									varyMatrixMode		= containsMatrices &&
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																								  (collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const int									numMatVariations	= varyMatrixMode ? 2 : 1;
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								if (containsMatrices && assignMethod != UniformValueCase::ASSIGNMETHOD_POINTER)
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									continue;
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								{
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const deUint32		booleanTypeFeat		= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: 0;
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const char* const	booleanTypeName		= booleanTypeI == 1 ? "int"
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: booleanTypeI == 2 ? "uint"
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			: "float";
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const string		nameWithBoolType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									for (int matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++)
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									{
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										const string nameWithMatrixType = nameWithBoolType + (matrixTypeI == 1 ? "row_major_" : "");
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										{
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const string	name							= nameWithMatrixType + getCaseShaderTypeName((CaseShaderType)shaderType);
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											const deUint32	arrayFirstElemNameNoIndexFeat	= referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX;
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							   UniformValueCase::VALUETOCHECK_ASSIGNED, checkMethod, assignMethod,
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							   booleanTypeFeat | arrayFirstElemNameNoIndexFeat | (matrixTypeI == 1 ? UniformCase::FEATURE_MATRIXMODE_ROWMAJOR : 0)));
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										}
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									}
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								}
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1).
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				static const struct
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					UniformCase::Feature	arrayAssignMode;
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*				name;
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*				description;
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				} arrayAssignGroups[] =
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{ UniformCase::FEATURE_ARRAYASSIGN_FULL,			"basic_array_assign_full",		"Assign entire basic-type arrays per glUniform*v() call"			},
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{ UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO,	"basic_array_assign_partial",	"Assign two elements of a basic-type array per glUniform*v() call"	}
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				};
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int arrayAssignGroupNdx = 0; arrayAssignGroupNdx < DE_LENGTH_OF_ARRAY(arrayAssignGroups); arrayAssignGroupNdx++)
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					UniformCase::Feature	arrayAssignMode		= arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* const		groupName			= arrayAssignGroups[arrayAssignGroupNdx].name;
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* const		groupDesc			= arrayAssignGroups[arrayAssignGroupNdx].description;
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* const curArrayAssignGroup = new TestCaseGroup(m_context, groupName, groupDesc);
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					assignedValuesGroup->addChild(curArrayAssignGroup);
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					static const int basicArrayCollectionGroups[] = { UNIFORMCOLLECTIONS_BASIC_ARRAY, UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT, UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY };
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionGroupNdx = 0; collectionGroupNdx < DE_LENGTH_OF_ARRAY(basicArrayCollectionGroups); collectionGroupNdx++)
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						curArrayAssignGroup->addChild(collectionTestGroup);
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string								collName			= collectionCase.namePrefix;
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								collectionTestGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				   arrayAssignMode));
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Value checking cases when unused uniforms are present.
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				assignedValuesGroup->addChild(unusedUniformsGroup);
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string								collName			= collectionCase.namePrefix;
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						unusedUniformsGroup->addChild(new UniformValueCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   UniformValueCase::VALUETOCHECK_ASSIGNED, UniformValueCase::CHECKMETHOD_GET_UNIFORM, UniformValueCase::ASSIGNMETHOD_POINTER,
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX | UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER));
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Random cases.
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numRandomCases		= 100;
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup*	const randomGroup	= new TestCaseGroup(m_context, "random", "Random cases");
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(randomGroup);
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < numRandomCases; ndx++)
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			randomGroup->addChild(new RandomUniformCase(m_context, de::toString(ndx).c_str(), "", (deUint32)ndx));
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2967