13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 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 glProgramUniform*() tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \todo [2013-02-26 nuutti] Much duplication between ES2&3 uniform api
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *							 tests and this. Utilities to glshared?
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fProgramUniformTests.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 "gluDrawUtil.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstring>
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::ScopedLogSection;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ShaderProgram;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::StructType;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::SharedPtr;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef bool (* dataTypePredicate)(glu::DataType);
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_RENDER_WIDTH			= 32,
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_RENDER_HEIGHT			= 32,
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_NUM_SAMPLER_UNIFORMS	= 16
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const glu::DataType s_testDataTypes[] =
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT,
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_VEC2,
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_VEC3,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_VEC4,
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT2,
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT2X3,
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT2X4,
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT3X2,
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT3,
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT3X4,
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT4X2,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT4X3,
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_FLOAT_MAT4,
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT,
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC2,
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC3,
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_INT_VEC4,
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT,
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT_VEC2,
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT_VEC3,
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_UINT_VEC4,
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL,
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC2,
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC3,
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_BOOL_VEC4,
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_SAMPLER_2D,
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TYPE_SAMPLER_CUBE
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note We don't test all sampler types here.
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getGLInt (const glw::Functions& funcs, const deUint32 name)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int val = -1;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	funcs.getIntegerv(name, &val);
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return val;
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Vec4 vec4FromPtr (const float* const ptr)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vec4 result;
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 4; i++)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = ptr[i];
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string beforeLast (const string& str, const char c)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str.substr(0, str.find_last_of(c));
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void fillWithColor (const tcu::PixelBufferAccess& access, const tcu::Vec4& color)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int z = 0; z < access.getDepth(); z++)
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < access.getHeight(); y++)
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < access.getWidth(); x++)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		access.setPixel(color, x, y, z);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getSamplerNumLookupDimensions (const glu::DataType type)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D:
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D:
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D:
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 2;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_3D:
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_3D:
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_3D:
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_SHADOW:
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY:
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE:
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE:
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE:
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 3;
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE_SHADOW:
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 4;
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline glu::DataType getSamplerLookupReturnType (const glu::DataType type)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D:
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE:
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY:
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_3D:
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT_VEC4;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D:
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE:
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_3D:
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_UINT_VEC4;
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D:
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE:
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_3D:
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_INT_VEC4;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_SHADOW:
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE_SHADOW:
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_FLOAT;
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::TYPE_LAST;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<glu::DataType T>
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool dataTypeEquals (const glu::DataType t)
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return t == T;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<int N>
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool dataTypeIsMatrixWithNRows (const glu::DataType t)
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::isDataTypeMatrix(t) && glu::getDataTypeMatrixNumRows(t) == N;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool typeContainsMatchingBasicType (const glu::VarType& type, const dataTypePredicate predicate)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return predicate(type.getBasicType());
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return typeContainsMatchingBasicType(type.getElementType(), predicate);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate))
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getDistinctSamplerTypes (vector<glu::DataType>& dst, const glu::VarType& type)
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType basicType = type.getBasicType();
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicType) && std::find(dst.begin(), dst.end(), basicType) == dst.end())
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.push_back(basicType);
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getDistinctSamplerTypes(dst, type.getElementType());
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getDistinctSamplerTypes(dst, structType.getMember(i).getType());
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumSamplersInType (const glu::VarType& type)
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isBasicType())
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return glu::isDataTypeSampler(type.getBasicType()) ? 1 : 0;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isArrayType())
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return getNumSamplersInType(type.getElementType()) * type.getArraySize();
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(type.isStructType());
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *type.getStructPtr();
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int sum = 0;
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sum += getNumSamplersInType(structType.getMember(i).getType());
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sum;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VarValue
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::DataType type;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	union
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float		floatV[4*4]; // At most mat4. \note Matrices here are column-major.
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt32		intV[4];
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	uintV[4];
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool		boolV[4];
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		struct
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		unit;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			union
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		floatV[4];
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deInt32		intV[4];
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deUint32	uintV[4];
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			} fillColor;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} samplerV;
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} val;
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum CaseShaderType
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_VERTEX = 0,
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_FRAGMENT,
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_BOTH,
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_LAST
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Uniform
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			name;
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::VarType	type;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Uniform (const char* const name_, const glu::VarType& type_) : name(name_), type(type_) {}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// A set of uniforms, along with related struct types.
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformCollection
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getNumUniforms		(void) const					{ return (int)m_uniforms.size();	}
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					getNumStructTypes	(void) const					{ return (int)m_structTypes.size();	}
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Uniform&			getUniform			(const int ndx)					{ return m_uniforms[ndx];			}
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Uniform&		getUniform			(const int ndx) const			{ return m_uniforms[ndx];			}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const StructType*	getStructType		(const int ndx) const			{ return m_structTypes[ndx];		}
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				addUniform			(const Uniform& uniform)		{ m_uniforms.push_back(uniform);	}
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void				addStructType		(const StructType* const type)	{ m_structTypes.push_back(type);	}
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollection	(void) {}
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	~UniformCollection	(void)
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_structTypes.size(); i++)
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete m_structTypes[i];
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one.
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note receiver takes ownership of the struct types.
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void moveContents (UniformCollection& receiver)
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			receiver.addUniform(m_uniforms[i]);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_uniforms.clear();
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_structTypes.size(); i++)
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			receiver.addStructType(m_structTypes[i]);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_structTypes.clear();
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool containsMatchingBasicType (const dataTypePredicate predicate) const
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (typeContainsMatchingBasicType(m_uniforms[i].type, predicate))
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::DataType> getSamplerTypes (void) const
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<glu::DataType> samplerTypes;
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			getDistinctSamplerTypes(samplerTypes, m_uniforms[i].type);
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return samplerTypes;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool containsSeveralSamplerTypes (void) const
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return getSamplerTypes().size() > 1;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int getNumSamplers (void) const
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int sum = 0;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniforms.size(); i++)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sum += getNumSamplersInType(m_uniforms[i].type);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return sum;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basic (const glu::DataType type, const char* const nameSuffix = "")
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(type, prec)));
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basicArray (const glu::DataType type, const char* const nameSuffix = "")
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec	= glu::isDataTypeBoolOrBVec(type) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->m_uniforms.push_back(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(glu::VarType(type, prec), 3)));
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* basicStruct (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec0	= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision		prec1	= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const structType = new StructType((string("structType") + nameSuffix).c_str());
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m0", glu::VarType(type0, prec0));
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m1", glu::VarType(type1, prec1));
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (containsArrays)
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember("m2", glu::VarType(glu::VarType(type0, prec0), 3));
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			structType->addMember("m3", glu::VarType(glu::VarType(type1, prec1), 3));
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(structType);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* structInArray (const glu::DataType type0, const glu::DataType type1, const bool containsArrays, const char* const nameSuffix = "")
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const res = basicStruct(type0, type1, containsArrays, nameSuffix);
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->getUniform(0).type = glu::VarType(res->getUniform(0).type, 3);
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* nestedArraysStructs (const glu::DataType type0, const glu::DataType type1, const char* const nameSuffix = "")
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const res		= new UniformCollection;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision prec0			= glu::isDataTypeBoolOrBVec(type0) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::Precision prec1			= glu::isDataTypeBoolOrBVec(type1) ? glu::PRECISION_LAST : glu::PRECISION_MEDIUMP;
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const structType		= new StructType((string("structType") + nameSuffix).c_str());
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const subStructType		= new StructType((string("subStructType") + nameSuffix).c_str());
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		StructType* const subSubStructType	= new StructType((string("subSubStructType") + nameSuffix).c_str());
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subSubStructType->addMember("mss0", glu::VarType(type0, prec0));
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subSubStructType->addMember("mss1", glu::VarType(type1, prec1));
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms0", glu::VarType(type1, prec1));
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms1", glu::VarType(glu::VarType(type0, prec0), 2));
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		subStructType->addMember("ms2", glu::VarType(glu::VarType(subSubStructType), 2));
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m0", glu::VarType(type0, prec0));
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m1", glu::VarType(subStructType));
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		structType->addMember("m2", glu::VarType(type1, prec1));
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(subSubStructType);
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(subStructType);
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addStructType(structType);
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res->addUniform(Uniform((string("u_var") + nameSuffix).c_str(), glu::VarType(structType)));
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleBasic (const char* const nameSuffix = "")
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4503c827367444ee418f129b2c238299f49d3264554Jarkko 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 };
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = basic(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleBasicArray (const char* const nameSuffix = "")
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types[]	= { glu::TYPE_FLOAT, glu::TYPE_INT_VEC3, glu::TYPE_BOOL_VEC2 };
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res		= new UniformCollection;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types); i++)
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = basicArray(types[i], ("_" + de::toString(i) + nameSuffix).c_str());
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static UniformCollection* multipleNestedArraysStructs (const char* const nameSuffix = "")
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types0[]	= { glu::TYPE_FLOAT,		glu::TYPE_INT,		glu::TYPE_BOOL_VEC4 };
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const glu::DataType	types1[]	= { glu::TYPE_FLOAT_VEC4,	glu::TYPE_INT_VEC4,	glu::TYPE_BOOL };
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformCollection* const	res			= new UniformCollection;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types0) == DE_LENGTH_OF_ARRAY(types1));
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(types0); i++)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCollection* const sub = nestedArraysStructs(types0[i], types1[i], ("_" + de::toString(i) + nameSuffix).c_str());
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sub->moveContents(*res);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete sub;
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return res;
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Copying these would be cumbersome, since deep-copying both m_uniforms and m_structTypes
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// would mean that we'd need to update pointers from uniforms to point to the new structTypes.
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// When the same UniformCollection is needed in several places, a SharedPtr is used instead.
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCollection	(const UniformCollection&); // Not allowed.
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollection&			operator=			(const UniformCollection&); // Not allowed.
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Uniform>				m_uniforms;
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<const StructType*>	m_structTypes;
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; // anonymous
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getSamplerFillValue (const VarValue& sampler)
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeSampler(sampler.type));
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue result;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = getSamplerLookupReturnType(sampler.type);
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (result.type)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_VEC4:
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.val.floatV[i] = sampler.val.samplerV.fillColor.floatV[i];
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_VEC4:
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.val.uintV[i] = sampler.val.samplerV.fillColor.uintV[i];
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_VEC4:
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < 4; i++)
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result.val.intV[i] = sampler.val.samplerV.fillColor.intV[i];
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT:
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.floatV[0] = sampler.val.samplerV.fillColor.floatV[0];
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getSamplerUnitValue (const VarValue& sampler)
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeSampler(sampler.type));
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue result;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = glu::TYPE_INT;
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.val.intV[0] = sampler.val.samplerV.unit;
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::DataType getDataTypeTransposedMatrix (const glu::DataType original)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return glu::getDataTypeMatrix(glu::getDataTypeMatrixNumRows(original), glu::getDataTypeMatrixNumColumns(original));
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getTransposeMatrix (const VarValue& original)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeMatrix(original.type));
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	rows = glu::getDataTypeMatrixNumRows(original.type);
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	cols = glu::getDataTypeMatrixNumColumns(original.type);
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue	result;
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = getDataTypeTransposedMatrix(original.type);
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < rows; i++)
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int j = 0; j < cols; j++)
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.floatV[i*cols + j] = original.val.floatV[j*rows + i];
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string shaderVarValueStr (const VarValue& value)
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numElems = glu::getDataTypeScalarSize(value.type);
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << glu::getDataTypeName(value.type) << "(";
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numElems; i++)
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i > 0)
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << ", ";
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::floatToString(value.val.floatV[i], 2);
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec((value.type)))
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.intV[i]);
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec((value.type)))
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.uintV[i]) << "u";
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec((value.type)))
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << (value.val.boolV[i] ? "true" : "false");
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler((value.type)))
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << shaderVarValueStr(getSamplerFillValue(value));
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << ")";
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string apiVarValueStr (const VarValue& value)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			numElems = glu::getDataTypeScalarSize(value.type);
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << "(";
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numElems; i++)
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i > 0)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << ", ";
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(value.type) || glu::isDataTypeMatrix(value.type))
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::floatToString(value.val.floatV[i], 2);
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec((value.type)))
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.intV[i]);
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec((value.type)))
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << de::toString(value.val.uintV[i]);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec((value.type)))
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << (value.val.boolV[i] ? "true" : "false");
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler((value.type)))
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result << value.val.samplerV.unit;
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numElems > 1)
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result << ")";
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko 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. */)
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	numElems = glu::getDataTypeScalarSize(type);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue	result;
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = type;
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((samplerUnit >= 0) == (glu::isDataTypeSampler(type)));
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(type) || glu::isDataTypeMatrix(type))
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(type))
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.intV[i] = rnd.getInt(-10, 10);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeUintOrUVec(type))
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.uintV[i] = (deUint32)rnd.getInt(0, 10);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(type))
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numElems; i++)
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.val.boolV[i] = rnd.getBool();
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(type))
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		texResultType		= getSamplerLookupReturnType(type);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		texResultScalarType	= glu::getDataTypeScalarType(texResultType);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				texResultNumDims	= glu::getDataTypeScalarSize(texResultType);
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.val.samplerV.unit = samplerUnit;
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < texResultNumDims; i++)
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (texResultScalarType)
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT:	result.val.samplerV.fillColor.floatV[i]		= rnd.getFloat(0.0f, 1.0f);		break;
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_INT:		result.val.samplerV.fillColor.intV[i]		= rnd.getInt(-10, 10);			break;
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_UINT:	result.val.samplerV.fillColor.uintV[i]		= (deUint32)rnd.getInt(0, 10);	break;
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool apiVarValueEquals (const VarValue& a, const VarValue& b)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		size			= glu::getDataTypeScalarSize(a.type);
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		floatThreshold	= 0.05f;
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(a.type == b.type);
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeFloatOrVec(a.type) || glu::isDataTypeMatrix(a.type))
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (de::abs(a.val.floatV[i] - b.val.floatV[i]) >= floatThreshold)
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeIntOrIVec(a.type))
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.intV[i] != b.val.intV[i])
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeUintOrUVec(a.type))
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.uintV[i] != b.val.uintV[i])
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeBoolOrBVec(a.type))
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < size; i++)
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (a.val.boolV[i] != b.val.boolV[i])
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (glu::isDataTypeSampler(a.type))
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (a.val.samplerV.unit != b.val.samplerV.unit)
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic VarValue getRandomBoolRepresentation (const VarValue& boolValue, const glu::DataType targetScalarType, Random& rnd)
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isDataTypeBoolOrBVec(boolValue.type));
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				size		= glu::getDataTypeScalarSize(boolValue.type);
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		targetType	= size == 1 ? targetScalarType : glu::getDataTypeVector(targetScalarType, size);
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VarValue				result;
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.type = targetType;
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (targetScalarType)
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT:
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.intV[i] = rnd.getInt(-10, 10);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (result.val.intV[i] == 0)
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						result.val.intV[i] = 1;
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.intV[i] = 0;
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT:
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.uintV[i] = rnd.getInt(1, 10);
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.uintV[i] = 0;
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT:
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < size; i++)
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (boolValue.val.boolV[i])
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.floatV[i] = rnd.getFloat(-10.0f, 10.0f);
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (result.val.floatV[i] == 0.0f)
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						result.val.floatV[i] = 1.0f;
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result.val.floatV[i] = 0;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getCaseShaderTypeName (const CaseShaderType type)
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_VERTEX:		return "vertex";
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_FRAGMENT:	return "fragment";
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_BOTH:		return "both";
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformCase : public TestCase, protected glu::CallLogWrapper
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum Feature
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices.
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX	= 1<<0,
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// UNIFORMFUNC_VALUE: use pass-by-value versions of uniform assignment funcs, e.g. glProgramUniform1f(), where possible. If not given, use pass-by-pointer versions.
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMFUNC_VALUE				= 1<<1,
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major.
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_MATRIXMODE_ROWMAJOR				= 1<<2,
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// ARRAYASSIGN: how basic-type arrays are assigned with glProgramUniform*(). If none given, assign each element of an array separately.
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYASSIGN_FULL				= 1<<3, //!< Assign all elements of an array with one glProgramUniform*().
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO		= 1<<4, //!< Assign two elements per one glProgramUniform*().
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8213c827367444ee418f129b2c238299f49d3264554Jarkko 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).
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_UNIFORMUSAGE_EVERY_OTHER		= 1<<5,
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float.
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_BOOLEANAPITYPE_INT				= 1<<6,
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_BOOLEANAPITYPE_UINT				= 1<<7,
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8283c827367444ee418f129b2c238299f49d3264554Jarkko 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.
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX	= 1<<8
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection);
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								UniformCase		(Context& context, const char* name, const char* description, CaseShaderType caseType, const SharedPtr<const UniformCollection>& uniformCollection, deUint32 features);
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~UniformCase	(void);
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				init			(void);
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				deinit			(void);
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate			(void);
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniform
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue		finalValue;	//!< The value we ultimately want to set for this uniform.
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8503c827367444ee418f129b2c238299f49d3264554Jarkko 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.
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				elemNdx;	//!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				rootSize;	//!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniform (const char* const		name_,
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const glu::DataType	type_,
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const bool			isUsedInShader_,
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const VarValue&		finalValue_,
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char* const		rootName_	= DE_NULL,
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				elemNdx_	= -1,
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const int				rootSize_	= 1)
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  : name			(name_)
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , type			(type_)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , isUsedInShader	(isUsedInShader_)
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , finalValue		(finalValue_)
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootName		(rootName_ == DE_NULL ? name_ : rootName_)
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , elemNdx			(elemNdx_)
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  , rootSize		(rootSize_)
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 {
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 }
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static vector<BasicUniform>::const_iterator findWithName (const vector<BasicUniform>& vec, const char* const name)
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (vector<BasicUniform>::const_iterator it = vec.begin(); it != vec.end(); it++)
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (it->name == name)
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return it;
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vec.end();
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniformsiv().
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BasicUniformReportRef
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string			name;
8863c827367444ee418f129b2c238299f49d3264554Jarkko 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.
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				minSize;
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				maxSize;
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::DataType	type;
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			isUsedInShader;
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const int minS, const int maxS, const glu::DataType type_, const bool used)
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(minS), maxSize(maxS), type(type_), isUsedInShader(used) { DE_ASSERT(minSize <= maxSize); }
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BasicUniformReportRef (const char* const name_, const glu::DataType type_, const bool used)
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: name(name_), minSize(1), maxSize(1), type(type_), isUsedInShader(used) {}
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Get uniform values with glGetUniform*() and put to valuesDst. Uniforms that get -1 from glGetUniformLocation() get glu::TYPE_INVALID.
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						getUniforms								(vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, deUint32 programGL);
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assign the basicUniforms[].finalValue values for uniforms. \note rnd parameter is for booleans (true can be any nonzero value).
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						assignUniforms							(const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd);
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare the uniform values given in values (obtained with glGetUniform*()) with the basicUniform.finalValue values.
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						compareUniformValues					(const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms);
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Render and check that all pixels are green (i.e. all uniform comparisons passed).
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						renderTest								(const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd);
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool				test									(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd) = 0;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32								m_features;
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const SharedPtr<const UniformCollection>	m_uniformCollection;
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generates the basic uniforms, based on the uniform with name varName and type varType, in the same manner as are expected
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// to be returned by glGetActiveUniform(), e.g. generates a name like var[0] for arrays, and recursively generates struct member names.
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						generateBasicUniforms					(vector<BasicUniform>&				basicUniformsDst,
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 vector<BasicUniformReportRef>&		basicUniformReportsDst,
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const glu::VarType&				varType,
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 const char*						varName,
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 bool								isParentActive,
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 int&								samplerUnitCounter,
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 Random&							rnd) const;
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformDefinitions					(std::ostringstream& dst) const;
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformCompareExpr					(std::ostringstream& dst, const BasicUniform& uniform) const;
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						writeUniformComparisons					(std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* variableName) const;
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateVertexSource					(const vector<BasicUniform>& basicUniforms) const;
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						generateFragmentSource					(const vector<BasicUniform>& basicUniforms) const;
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupTexture							(const VarValue& value);
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseShaderType						m_caseShaderType;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::Texture2D*>						m_textures2d;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::TextureCube*>					m_texturesCube;
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint32>							m_filledTextureUnits;
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection, const deUint32 features)
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(features)
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(uniformCollection)
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(caseShaderType)
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::UniformCase (Context& context, const char* const name, const char* const description, const CaseShaderType caseShaderType, const SharedPtr<const UniformCollection>& uniformCollection)
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(context, name, description)
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, CallLogWrapper		(context.getRenderContext().getFunctions(), m_testCtx.getLog())
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_features			(0)
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformCollection	(uniformCollection)
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_caseShaderType		(caseShaderType)
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::init (void)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glw::Functions&	funcs						= m_context.getRenderContext().getFunctions();
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numSamplerUniforms			= m_uniformCollection->getNumSamplers();
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsRequired		= m_caseShaderType != CASESHADERTYPE_FRAGMENT ? numSamplerUniforms : 0;
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsRequired	= m_caseShaderType != CASESHADERTYPE_VERTEX ? numSamplerUniforms : 0;
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsRequired	= vertexTexUnitsRequired + fragmentTexUnitsRequired;
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				vertexTexUnitsSupported		= getGLInt(funcs, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				fragmentTexUnitsSupported	= getGLInt(funcs, GL_MAX_TEXTURE_IMAGE_UNITS);
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				combinedTexUnitsSupported	= getGLInt(funcs, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numSamplerUniforms <= MAX_NUM_SAMPLER_UNIFORMS);
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexTexUnitsRequired > vertexTexUnitsSupported)
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(vertexTexUnitsRequired) + " vertex texture units required, " + de::toString(vertexTexUnitsSupported) + " supported");
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(fragmentTexUnitsRequired) + " fragment texture units required, " + de::toString(fragmentTexUnitsSupported) + " supported");
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (combinedTexUnitsRequired > combinedTexUnitsSupported)
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError(de::toString(combinedTexUnitsRequired) + " combined texture units required, " + de::toString(combinedTexUnitsSupported) + " supported");
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::deinit (void)
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_textures2d.size(); i++)
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures2d[i];
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures2d.clear();
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_texturesCube.size(); i++)
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_texturesCube[i];
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texturesCube.clear();
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_filledTextureUnits.clear();
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::~UniformCase (void)
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCase::deinit();
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10003c827367444ee418f129b2c238299f49d3264554Jarkko 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
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType())
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isActive	= isParentActive && (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.size() % 2 == 0 : true);
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		type		= varType.getBasicType();
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue			value		= glu::isDataTypeSampler(type) ? generateRandomVarValue(type, rnd, samplerUnitCounter++)
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   : generateRandomVarValue(varType.getBasicType(), rnd);
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformsDst.push_back(BasicUniform(varName, varType.getBasicType(), isActive, value));
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		basicUniformReportsDst.push_back(BasicUniformReportRef(varName, varType.getBasicType(), isActive));
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isArrayType())
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		size			= varType.getArraySize();
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	arrayRootName	= string("") + varName + "[0]";
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<bool>	isElemActive;
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++)
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	indexedName		= string("") + varName + "[" + de::toString(elemNdx) + "]";
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		isCurElemActive	= isParentActive																						&&
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_UNIFORMUSAGE_EVERY_OTHER			? basicUniformsDst.size() % 2 == 0	: true)	&&
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											  (m_features & FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX		? elemNdx == size/2					: true);
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			isElemActive.push_back(isCurElemActive);
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (varType.getElementType().isBasicType())
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::DataType	elemBasicType	= varType.getElementType().getBasicType();
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const VarValue		value			= glu::isDataTypeSampler(elemBasicType) ? generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++)
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							: generateRandomVarValue(elemBasicType, rnd);
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				basicUniformsDst.push_back(BasicUniform(indexedName.c_str(), elemBasicType, isCurElemActive, value, arrayRootName.c_str(), elemNdx, size));
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName.c_str(), isCurElemActive, samplerUnitCounter, rnd);
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (varType.getElementType().isBasicType())
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int minSize;
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize-1]; minSize--);
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			basicUniformReportsDst.push_back(BasicUniformReportRef(arrayRootName.c_str(), minSize, size, varType.getElementType().getBasicType(), isParentActive && minSize > 0));
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(varType.isStructType());
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const StructType& structType = *varType.getStructPtr();
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < structType.getNumMembers(); i++)
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::StructMember&	member			= structType.getMember(i);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string				memberFullName	= string("") + varName + "." + member.getName();
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName.c_str(), isParentActive, samplerUnitCounter, rnd);
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformDefinitions (std::ostringstream& dst) const
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumStructTypes(); i++)
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << glu::declare(m_uniformCollection->getStructType(i)) << ";\n";
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "uniform " << glu::declare(m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str()) << ";\n";
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << "\n";
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const struct
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataTypePredicate	requiringTypes[2];
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*			definition;
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} compareFuncs[] =
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10813c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																		},
10823c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"														},
10833c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"								},
10843c827367444ee418f129b2c238299f49d3264554Jarkko 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); }"		},
10853c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"													},
10863c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"													},
10873c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"													},
10883c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"							},
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_MAT3>,	dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_mat3     (mediump mat3 a, mediump mat3 b)    { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2]); }"							},
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_FLOAT_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]); }"							},
10913c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"	},
10923c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"	},
10933c827367444ee418f129b2c238299f49d3264554Jarkko 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]); }"	},
10943c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10953c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10963c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10973c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10983c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
10993c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
11003c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
11013c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ { dataTypeEquals<glu::TYPE_BOOL>,			dataTypeEquals<glu::TYPE_INVALID>	}, "mediump float compare_bool     (bool a, bool b)                    { return a == b ? 1.0 : 0.0; }"																					},
11033c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
11043c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					},
11053c827367444ee418f129b2c238299f49d3264554Jarkko 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; }"																					}
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<glu::DataType> samplerTypes = m_uniformCollection->getSamplerTypes();
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int compFuncNdx = 0; compFuncNdx < DE_LENGTH_OF_ARRAY(compareFuncs); compFuncNdx++)
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const dataTypePredicate		(&typeReq)[2]			= compareFuncs[compFuncNdx].requiringTypes;
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool						containsTypeSampler		= false;
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)samplerTypes.size(); i++)
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (glu::isDataTypeSampler(samplerTypes[i]))
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const glu::DataType retType = getSamplerLookupReturnType(samplerTypes[i]);
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (typeReq[0](retType) || typeReq[1](retType))
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						containsTypeSampler = true;
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (containsTypeSampler || m_uniformCollection->containsMatchingBasicType(typeReq[0]) || m_uniformCollection->containsMatchingBasicType(typeReq[1]))
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst << compareFuncs[compFuncNdx].definition << "\n";
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformCompareExpr (std::ostringstream& dst, const BasicUniform& uniform) const
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeSampler(uniform.type))
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_" << glu::getDataTypeName(getSamplerLookupReturnType(uniform.type)) << "(texture(" << uniform.name << ", vec" << getSamplerNumLookupDimensions(uniform.type) << "(0.0))";
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst << "compare_" << glu::getDataTypeName(uniform.type) << "(" << uniform.name;
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dst << ", " << shaderVarValueStr(uniform.finalValue) << ")";
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::writeUniformComparisons (std::ostringstream& dst, const vector<BasicUniform>& basicUniforms, const char* const variableName) const
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform& unif = basicUniforms[i];
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unif.isUsedInShader)
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t" << variableName << " *= ";
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeUniformCompareExpr(dst, basicUniforms[i]);
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << ";\n";
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst << "\t// UNUSED: " << basicUniforms[i].name << "\n";
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateVertexSource (const vector<BasicUniform>& basicUniforms) const
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX || m_caseShaderType == CASESHADERTYPE_BOTH;
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "#version 310 es\n"
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "in highp vec4 a_position;\n"
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "out mediump float v_vtxOut;\n"
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	gl_Position = a_position;\n"
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	v_vtxOut = 1.0;\n";
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "v_vtxOut");
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "}\n";
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UniformCase::generateFragmentSource (const vector<BasicUniform>& basicUniforms) const
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isFragmentCase = m_caseShaderType == CASESHADERTYPE_FRAGMENT || m_caseShaderType == CASESHADERTYPE_BOTH;
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	result;
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "#version 310 es\n"
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "in mediump float v_vtxOut;\n"
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n";
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformDefinitions(result);
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "\n"
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "\n"
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "void main (void)\n"
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "{\n"
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "	mediump float result = v_vtxOut;\n";
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isFragmentCase)
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		writeUniformComparisons(result, basicUniforms, "result");
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result << "	dEQP_FragColor = vec4(1.0-result, result, 0.0, 1.0);\n"
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  "}\n";
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result.str();
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::setupTexture (const VarValue& value)
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note No handling for samplers other than 2D or cube.
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(false);
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(getSamplerLookupReturnType(value.type) == glu::TYPE_FLOAT_VEC4);
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						width			= 32;
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int						height			= 32;
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec4					color			= vec4FromPtr(&value.val.samplerV.fillColor.floatV[0]);
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (value.type == glu::TYPE_SAMPLER_2D)
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Texture2D* texture		= new glu::Texture2D(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width, height);
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Texture2D& refTexture	= texture->getRefTexture();
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures2d.push_back(texture);
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		refTexture.allocLevel(0);
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fillWithColor(refTexture.getLevel(0), color);
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (value.type == glu::TYPE_SAMPLER_CUBE)
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(width == height);
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::TextureCube* texture		= new glu::TextureCube(m_context.getRenderContext(), GL_RGBA, GL_UNSIGNED_BYTE, width);
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureCube& refTexture	= texture->getRefTexture();
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_texturesCube.push_back(texture);
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			refTexture.allocLevel((tcu::CubeFace)face, 0);
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fillWithColor(refTexture.getLevelFace(0, (tcu::CubeFace)face), color);
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0 + value.val.samplerV.unit));
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_filledTextureUnits.push_back(value.val.samplerV.unit);
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture->upload();
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enableLogging(true);
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::getUniforms (vector<VarValue>& valuesDst, const vector<BasicUniform>& basicUniforms, const deUint32 programGL)
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName	= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				location	= glGetUniformLocation(programGL, queryName.c_str());
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				size		= glu::getDataTypeScalarSize(uniform.type);
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VarValue				value;
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemset(&value, 0xcd, sizeof(value)); // Initialize to known garbage.
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location == -1)
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.type = glu::TYPE_INVALID;
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesDst.push_back(value);
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (uniform.isUsedInShader)
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// FAILURE: " << uniform.name << " was used in shader, but has location -1" << TestLog::EndMessage;
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				success = false;
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		value.type = uniform.type;
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLint) == sizeof(value.val.intV[0]));
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(value.val.uintV[0]));
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(value.val.floatV[0]));
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(uniform.type) || glu::isDataTypeMatrix(uniform.type))
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(uniform.type))
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec(uniform.type))
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeBoolOrBVec(uniform.type))
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_features & FEATURE_BOOLEANAPITYPE_INT)
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformiv(programGL, location, &value.val.intV[0]));
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.intV[i] != 0;
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_features & FEATURE_BOOLEANAPITYPE_UINT)
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformuiv(programGL, location, &value.val.uintV[0]));
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.uintV[i] != 0;
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // Default: use float.
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glGetUniformfv(programGL, location, &value.val.floatV[0]));
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < size; i++)
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					value.val.boolV[i] = value.val.floatV[i] != 0.0f;
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(uniform.type))
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLint unit = -1;
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLU_CHECK_CALL(glGetUniformiv(programGL, location, &unit));
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			value.val.samplerV.unit = unit;
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		valuesDst.push_back(value);
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Got " << uniform.name << " value " << apiVarValueStr(value) << TestLog::EndMessage;
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UniformCase::assignUniforms (const vector<BasicUniform>& basicUniforms, deUint32 programGL, Random& rnd)
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log				= m_testCtx.getLog();
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				transpose		= (m_features & FEATURE_MATRIXMODE_ROWMAJOR) != 0;
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLboolean			transposeGL		= transpose ? GL_TRUE : GL_FALSE;
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::DataType		boolApiType		= m_features & FEATURE_BOOLEANAPITYPE_INT	? glu::TYPE_INT
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: m_features & FEATURE_BOOLEANAPITYPE_UINT	? glu::TYPE_UINT
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											:											  glu::TYPE_FLOAT;
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform				= basicUniforms[unifNdx];
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				isArrayMember		= uniform.elemNdx >= 0;
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string			queryName			= m_features & FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? beforeLast(uniform.name, '[') : uniform.name;
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				numValuesToAssign	= !isArrayMember									? 1
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_FULL				? (uniform.elemNdx == 0			? uniform.rootSize	: 0)
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: m_features & FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO	? (uniform.elemNdx % 2 == 0		? 2					: 0)
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: /* Default: assign array elements separately */	  1;
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign >= 0);
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numValuesToAssign == 1 || isArrayMember);
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numValuesToAssign == 0)
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Uniform " << uniform.name << " is covered by another glProgramUniform*v() call to the same array" << TestLog::EndMessage;
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			location			= glGetUniformLocation(programGL, queryName.c_str());
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			typeSize			= glu::getDataTypeScalarSize(uniform.type);
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			assignByValue		= m_features & FEATURE_UNIFORMFUNC_VALUE && !glu::isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue>	valuesToAssign;
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < numValuesToAssign; i++)
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string	curName = isArrayMember ? beforeLast(uniform.rootName, '[') + "[" + de::toString(uniform.elemNdx+i) + "]" : uniform.name;
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VarValue		unifValue;
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isArrayMember)
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const vector<BasicUniform>::const_iterator elemUnif = BasicUniform::findWithName(basicUniforms, curName.c_str());
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (elemUnif == basicUniforms.end())
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = elemUnif->finalValue;
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unifValue = uniform.finalValue;
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const VarValue apiValue = glu::isDataTypeBoolOrBVec(unifValue.type)	? getRandomBoolRepresentation(unifValue, boolApiType, rnd)
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: glu::isDataTypeSampler(unifValue.type)	? getSamplerUnitValue(unifValue)
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: unifValue;
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			valuesToAssign.push_back(glu::isDataTypeMatrix(apiValue.type) && transpose ? getTransposeMatrix(apiValue) : apiValue);
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isDataTypeBoolOrBVec(uniform.type))
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Using type " << glu::getDataTypeName(boolApiType) << " to set boolean value " << apiVarValueStr(unifValue) << " for " << curName << TestLog::EndMessage;
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (glu::isDataTypeSampler(uniform.type))
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "// Texture for the sampler uniform " << curName << " will be filled with color " << apiVarValueStr(getSamplerFillValue(uniform.finalValue)) << TestLog::EndMessage;
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!valuesToAssign.empty());
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeFloatOrVec(valuesToAssign[0].type))
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float* const ptr = &valuesToAssign[0].val.floatV[0];
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glProgramUniform1f(programGL, location, ptr[0]));							break;
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glProgramUniform2f(programGL, location, ptr[0], ptr[1]));					break;
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glProgramUniform3f(programGL, location, ptr[0], ptr[1], ptr[2]));			break;
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glProgramUniform4f(programGL, location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<float> buffer(valuesToAssign.size() * typeSize);
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glProgramUniform1fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glProgramUniform2fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glProgramUniform3fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glProgramUniform4fv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeMatrix(valuesToAssign[0].type))
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!assignByValue);
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<float> buffer(valuesToAssign.size() * typeSize);
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)buffer.size(); i++)
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				buffer[i] = valuesToAssign[i / typeSize].val.floatV[i % typeSize];
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(buffer[0]));
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (uniform.type)
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2:		GLU_CHECK_CALL(glProgramUniformMatrix2fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3:		GLU_CHECK_CALL(glProgramUniformMatrix3fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4:		GLU_CHECK_CALL(glProgramUniformMatrix4fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2X3:	GLU_CHECK_CALL(glProgramUniformMatrix2x3fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT2X4:	GLU_CHECK_CALL(glProgramUniformMatrix2x4fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3X2:	GLU_CHECK_CALL(glProgramUniformMatrix3x2fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT3X4:	GLU_CHECK_CALL(glProgramUniformMatrix3x4fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4X2:	GLU_CHECK_CALL(glProgramUniformMatrix4x2fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case glu::TYPE_FLOAT_MAT4X3:	GLU_CHECK_CALL(glProgramUniformMatrix4x3fv	(programGL, location, (GLsizei)valuesToAssign.size(), transposeGL, &buffer[0])); break;
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeIntOrIVec(valuesToAssign[0].type))
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deInt32* const ptr = &valuesToAssign[0].val.intV[0];
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glProgramUniform1i(programGL, location, ptr[0]));							break;
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glProgramUniform2i(programGL, location, ptr[0], ptr[1]));					break;
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glProgramUniform3i(programGL, location, ptr[0], ptr[1], ptr[2]));			break;
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glProgramUniform4i(programGL, location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<deInt32> buffer(valuesToAssign.size() * typeSize);
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLint) == sizeof(buffer[0]));
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glProgramUniform1iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glProgramUniform2iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glProgramUniform3iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glProgramUniform4iv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeUintOrUVec(valuesToAssign[0].type))
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32* const ptr = &valuesToAssign[0].val.uintV[0];
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glProgramUniform1ui(programGL, location, ptr[0]));							break;
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glProgramUniform2ui(programGL, location, ptr[0], ptr[1]));					break;
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glProgramUniform3ui(programGL, location, ptr[0], ptr[1], ptr[2]));			break;
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glProgramUniform4ui(programGL, location, ptr[0], ptr[1], ptr[2], ptr[3]));	break;
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<deUint32> buffer(valuesToAssign.size() * typeSize);
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int i = 0; i < (int)buffer.size(); i++)
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					buffer[i] = valuesToAssign[i / typeSize].val.intV[i % typeSize];
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_STATIC_ASSERT(sizeof(GLuint) == sizeof(buffer[0]));
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (typeSize)
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 1: GLU_CHECK_CALL(glProgramUniform1uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 2: GLU_CHECK_CALL(glProgramUniform2uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 3: GLU_CHECK_CALL(glProgramUniform3uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case 4: GLU_CHECK_CALL(glProgramUniform4uiv(programGL, location, (GLsizei)valuesToAssign.size(), &buffer[0])); break;
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(false);
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (glu::isDataTypeSampler(valuesToAssign[0].type))
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (assignByValue)
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glProgramUniform1i(programGL, location, uniform.finalValue.val.samplerV.unit));
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const GLint unit = uniform.finalValue.val.samplerV.unit;
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GLU_CHECK_CALL(glProgramUniform1iv(programGL, location, (GLsizei)valuesToAssign.size(), &unit));
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::compareUniformValues (const vector<VarValue>& values, const vector<BasicUniform>& basicUniforms)
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&	log			= m_testCtx.getLog();
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		success		= true;
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unifNdx = 0; unifNdx < (int)basicUniforms.size(); unifNdx++)
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const BasicUniform&		uniform		= basicUniforms[unifNdx];
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const VarValue&			unifValue	= values[unifNdx];
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "// Checking uniform " << uniform.name << TestLog::EndMessage;
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unifValue.type == glu::TYPE_INVALID) // This happens when glGetUniformLocation() returned -1.
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!apiVarValueEquals(unifValue, uniform.finalValue))
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// FAILURE: value obtained with glGetUniform*() for uniform " << uniform.name << " differs from value set with glProgramUniform*()" << TestLog::EndMessage;
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			success = false;
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return success;
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformCase::renderTest (const vector<BasicUniform>& basicUniforms, const ShaderProgram& program, Random& rnd)
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log				= m_testCtx.getLog();
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportW		= de::min<int>(renderTarget.getWidth(),		MAX_RENDER_WIDTH);
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportH		= de::min<int>(renderTarget.getHeight(),	MAX_RENDER_HEIGHT);
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportX		= rnd.getInt(0, renderTarget.getWidth()		- viewportW);
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					viewportY		= rnd.getInt(0, renderTarget.getHeight()	- viewportH);
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface				renderedImg		(viewportW, viewportH);
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assert that no two samplers of different types have the same texture unit - this is an error in GL.
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type))
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int j = 0; j < i; j++)
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (glu::isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit);
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)basicUniforms.size(); i++)
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeSampler(basicUniforms[i].type) && std::find(m_filledTextureUnits.begin(), m_filledTextureUnits.end(), basicUniforms[i].finalValue.val.samplerV.unit) == m_filledTextureUnits.end())
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "// Filling texture at unit " << apiVarValueStr(basicUniforms[i].finalValue) << " with color " << shaderVarValueStr(basicUniforms[i].finalValue) << TestLog::EndMessage;
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setupTexture(basicUniforms[i].finalValue);
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportW, viewportH));
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_CHECK_CALL(glUseProgram(program.getProgram()));
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const float position[] =
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, -1.0f, 0.0f, 1.0f,
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			-1.0f, +1.0f, 0.0f, 1.0f,
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, -1.0f, 0.0f, 1.0f,
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+1.0f, +1.0f, 0.0f, 1.0f
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const deUint16			indices[]	= { 0, 1, 2, 2, 1, 3 };
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::VertexArrayBinding	binding		= glu::va::Float("a_position", 4, 4, 0, &position[0]);
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &binding, glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numFailedPixels = 0;
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < renderedImg.getHeight(); y++)
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < renderedImg.getWidth(); x++)
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (renderedImg.getPixel(x, y) != tcu::RGBA::green)
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				numFailedPixels += 1;
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numFailedPixels > 0)
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "FAILURE: image comparison failed, got " << numFailedPixels << " non-green pixels" << TestLog::EndMessage;
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Success: got all-green pixels (all uniforms have correct values)" << TestLog::EndMessage;
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformCase::IterateResult UniformCase::iterate (void)
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Random							rnd				(deStringHash(getName()) ^ (deUint32)m_context.getTestContext().getCommandLine().getBaseSeed());
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log				= m_testCtx.getLog();
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniform>			basicUniforms;
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<BasicUniformReportRef>	basicUniformReportsRef;
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int samplerUnitCounter = 0;
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)m_uniformCollection->getNumUniforms(); i++)
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			generateBasicUniforms(basicUniforms, basicUniformReportsRef, m_uniformCollection->getUniform(i).type, m_uniformCollection->getUniform(i).name.c_str(), true, samplerUnitCounter, rnd);
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					vertexSource	= generateVertexSource(basicUniforms);
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string					fragmentSource	= generateFragmentSource(basicUniforms);
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderProgram				program			(m_context.getRenderContext(), glu::makeVtxFragSources(vertexSource, fragmentSource));
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// A dummy program that we'll give to glUseProgram before we actually need
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// the real program above, to see if an implementation tries to use the
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// currently active program for something inappropriate (instead of the
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// program given as argument to, say, glProgramUniform*).
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ShaderProgram				dummyProgram	(m_context.getRenderContext(), glu::makeVtxFragSources("#version 310 es\n"
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																										   "void main (void) { gl_Position = vec4(1.0); }\n",
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																										   "#version 310 es\n"
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																										   "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																										   "void main (void) { dEQP_FragColor = vec4(0.0, 0.0, 1.0, 1.0); }\n"));
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << program;
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program.isOk())
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!dummyProgram.isOk())
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << dummyProgram;
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of dummy program failed");
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "// Note: calling glUseProgram with a dummy program (will only use the real program once it's needed for rendering)" << TestLog::EndMessage;
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(dummyProgram.getProgram());
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool success = test(basicUniforms, basicUniformReportsRef, program, rnd);
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							success ? "Passed"				: "Failed");
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UniformAssignCase : public UniformCase
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CheckMethod
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_GET_UNIFORM = 0,	//!< Check values with glGetUniform*().
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_RENDER,				//!< Check values by rendering with the value-checking shader.
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CHECKMETHOD_LAST
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum AssignMethod
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_POINTER = 0,
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_VALUE,
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ASSIGNMETHOD_LAST
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						UniformAssignCase			(Context&									context,
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								name,
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*								description,
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CaseShaderType								shaderType,
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const SharedPtr<const UniformCollection>&	uniformCollection,
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 CheckMethod								checkMethod,
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 AssignMethod								assignMethod,
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 deUint32									additionalFeatures = 0);
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				test						(const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd);
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodName			(CheckMethod checkMethod);
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getCheckMethodDescription	(CheckMethod checkMethod);
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodName			(AssignMethod checkMethod);
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char*	getAssignMethodDescription	(AssignMethod checkMethod);
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CheckMethod m_checkMethod;
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformAssignCase::getCheckMethodName (const CheckMethod checkMethod)
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "get_uniform";
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "render";
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformAssignCase::getCheckMethodDescription (const CheckMethod checkMethod)
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (checkMethod)
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_GET_UNIFORM:	return "Verify values with glGetUniform*()";
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CHECKMETHOD_RENDER:		return "Verify values by rendering";
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformAssignCase::getAssignMethodName (const AssignMethod assignMethod)
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "by_pointer";
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "by_value";
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* UniformAssignCase::getAssignMethodDescription (const AssignMethod assignMethod)
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (assignMethod)
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_POINTER:		return "Assign values by-pointer";
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case ASSIGNMETHOD_VALUE:		return "Assign values by-value";
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(false);		return DE_NULL;
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUniformAssignCase::UniformAssignCase (Context&									context,
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const char* const							name,
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const char* const							description,
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const CaseShaderType						shaderType,
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const SharedPtr<const UniformCollection>&	uniformCollection,
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const CheckMethod							checkMethod,
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const AssignMethod						assignMethod,
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const deUint32							additionalFeatures)
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: UniformCase		(context, name, description, shaderType, uniformCollection,
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 (assignMethod == ASSIGNMETHOD_VALUE ? FEATURE_UNIFORMFUNC_VALUE : 0) | additionalFeatures)
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_checkMethod		(checkMethod)
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(assignMethod != ASSIGNMETHOD_LAST);
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool UniformAssignCase::test (const vector<BasicUniform>& basicUniforms, const vector<BasicUniformReportRef>& basicUniformReportsRef, const ShaderProgram& program, Random& rnd)
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(basicUniformReportsRef);
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	programGL	= program.getProgram();
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&		log			= m_testCtx.getLog();
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "UniformAssign", "Uniform value assignments");
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		assignUniforms(basicUniforms, programGL, rnd);
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_checkMethod == CHECKMETHOD_GET_UNIFORM)
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VarValue> values;
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "GetUniforms", "Uniform value query");
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = getUniforms(values, basicUniforms, program.getProgram());
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values");
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool success = compareUniformValues(values, basicUniforms);
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!success)
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_checkMethod == CHECKMETHOD_RENDER);
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ScopedLogSection section(log, "RenderTest", "Render test");
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool success = renderTest(basicUniforms, program, rnd);
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!success)
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramUniformTests::ProgramUniformTests (Context& context)
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "program_uniform", "glProgramUniform*() tests")
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramUniformTests::~ProgramUniformTests (void)
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note Although this is only used in ProgramUniformTests::init, it needs to be defined here as it's used as a template argument.
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct UniformCollectionCase
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string								namePrefix;
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SharedPtr<const UniformCollection>	uniformCollection;
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniformCollectionCase (const char* const name, const UniformCollection* uniformCollection_)
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: namePrefix			(name ? name + string("_") : "")
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, uniformCollection		(uniformCollection_)
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ProgramUniformTests::init (void)
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Generate sets of UniformCollections that are used by several cases.
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC = 0,
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_ARRAY,
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_BASIC_STRUCT,
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY,
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT,
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS,
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC,
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY,
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS,
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UNIFORMCOLLECTIONS_LAST
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct UniformCollectionGroup
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string							name;
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<UniformCollectionCase>	cases;
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} defaultUniformCollections[UNIFORMCOLLECTIONS_LAST];
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].name							= "basic";
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].name						= "basic_array";
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].name						= "basic_struct";
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].name					= "struct_in_array";
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].name					= "array_in_struct";
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].name			= "nested_structs_arrays";
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].name					= "multiple_basic";
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].name				= "multiple_basic_array";
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].name	= "multiple_nested_structs_arrays";
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_testDataTypes); dataTypeNdx++)
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const glu::DataType		dataType	= s_testDataTypes[dataTypeNdx];
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const		typeName	= glu::getDataTypeName(dataType);
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basic(dataType)));
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)													||
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(glu::isDataTypeVector(dataType) && glu::getDataTypeScalarSize(dataType) == 4)	||
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4												||
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_ARRAY].cases.push_back(UniformCollectionCase(typeName, UniformCollection::basicArray(dataType)));
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeScalar(dataType)		||
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_FLOAT_MAT4	||
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dataType == glu::TYPE_SAMPLER_2D)
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const glu::DataType		secondDataType	= glu::isDataTypeScalar(dataType)	? glu::getDataTypeVector(dataType, 4)
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_FLOAT_MAT4	? glu::TYPE_FLOAT_MAT2
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: dataType == glu::TYPE_SAMPLER_2D	? glu::TYPE_SAMPLER_CUBE
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: glu::TYPE_LAST;
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(secondDataType != glu::TYPE_LAST);
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		secondTypeName	= glu::getDataTypeName(secondDataType);
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string			name			= string("") + typeName + "_" + secondTypeName;
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_BASIC_STRUCT].cases.push_back			(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, false)));
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::basicStruct(dataType, secondDataType, true)));
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_STRUCT_IN_ARRAY].cases.push_back		(UniformCollectionCase(name.c_str(), UniformCollection::structInArray(dataType, secondDataType, false)));
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			defaultUniformCollections[UNIFORMCOLLECTIONS_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(name.c_str(), UniformCollection::nestedArraysStructs(dataType, secondDataType)));
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC].cases.push_back					(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasic()));
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY].cases.push_back				(UniformCollectionCase(DE_NULL, UniformCollection::multipleBasicArray()));
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	defaultUniformCollections[UNIFORMCOLLECTIONS_MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push_back	(UniformCollectionCase(DE_NULL, UniformCollection::multipleNestedArraysStructs()));
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Basic by-pointer or by-value uniform assignment cases.
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int assignMethodI = 0; assignMethodI < (int)UniformAssignCase::ASSIGNMETHOD_LAST; assignMethodI++)
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const UniformAssignCase::AssignMethod	assignMethod		= (UniformAssignCase::AssignMethod)assignMethodI;
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const					assignMethodGroup	= new TestCaseGroup(m_context, UniformAssignCase::getAssignMethodName(assignMethod), UniformAssignCase::getAssignMethodDescription(assignMethod));
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(assignMethodGroup);
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int checkMethodI = 0; checkMethodI < (int)UniformAssignCase::CHECKMETHOD_LAST; checkMethodI++)
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformAssignCase::CheckMethod	checkMethod			= (UniformAssignCase::CheckMethod)checkMethodI;
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const					checkMethodGroup	= new TestCaseGroup(m_context, UniformAssignCase::getCheckMethodName(checkMethod), UniformAssignCase::getCheckMethodDescription(checkMethod));
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			assignMethodGroup->addChild(checkMethodGroup);
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int collectionGroupNdx = 0; collectionGroupNdx < (int)UNIFORMCOLLECTIONS_LAST; collectionGroupNdx++)
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int numArrayFirstElemNameCases = checkMethod == UniformAssignCase::CHECKMETHOD_GET_UNIFORM && collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY ? 2 : 1;
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++)
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionGroup&	collectionGroup			= defaultUniformCollections[collectionGroupNdx];
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string					collectionGroupName		= collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? "" : "_first_elem_without_brackets");
1964ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry					TestCaseGroup*					collectionTestGroup		= DE_NULL;
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string								collName			= collectionCase.namePrefix;
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									containsBooleans	= uniformCollection->containsMatchingBasicType(glu::isDataTypeBoolOrBVec);
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									varyBoolApiType		= checkMethod == UniformAssignCase::CHECKMETHOD_GET_UNIFORM && containsBooleans &&
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							(collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int									numBoolVariations	= varyBoolApiType ? 3 : 1;
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									containsMatrices	= uniformCollection->containsMatchingBasicType(glu::isDataTypeMatrix);
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool									varyMatrixMode		= containsMatrices &&
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																							(collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC || collectionGroupNdx == UNIFORMCOLLECTIONS_BASIC_ARRAY);
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const int									numMatVariations	= varyMatrixMode ? 2 : 1;
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (containsMatrices && assignMethod != UniformAssignCase::ASSIGNMETHOD_POINTER)
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							continue;
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++)
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const deUint32		booleanTypeFeat		= booleanTypeI == 1 ? UniformCase::FEATURE_BOOLEANAPITYPE_INT
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	: booleanTypeI == 2 ? UniformCase::FEATURE_BOOLEANAPITYPE_UINT
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	: 0;
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char* const	booleanTypeName		= booleanTypeI == 1 ? "int"
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	: booleanTypeI == 2 ? "uint"
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	: "float";
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const string		nameWithBoolType	= varyBoolApiType ? collName + "api_" + booleanTypeName + "_" : collName;
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							for (int matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++)
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							{
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								const string nameWithMatrixType = nameWithBoolType + (matrixTypeI == 1 ? "row_major_" : "");
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								{
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const string	name							= nameWithMatrixType + getCaseShaderTypeName((CaseShaderType)shaderType);
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const deUint32	arrayFirstElemNameNoIndexFeat	= referToFirstArrayElemWithoutIndexI == 0 ? 0 : UniformCase::FEATURE_ARRAY_FIRST_ELEM_NAME_NO_INDEX;
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2002ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry									// skip empty groups by creating groups on demand
2003ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry									if (!collectionTestGroup)
2004ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry									{
2005ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										collectionTestGroup = new TestCaseGroup(m_context, collectionGroupName.c_str(), "");
2006ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry										checkMethodGroup->addChild(collectionTestGroup);
2007ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry									}
2008ee2e92c10d529b2be9ef1279655f9b65a3f1a407Jarkko Pöyry
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									collectionTestGroup->addChild(new UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																						checkMethod, assignMethod,
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																						booleanTypeFeat | arrayFirstElemNameNoIndexFeat | (matrixTypeI == 1 ? UniformCase::FEATURE_MATRIXMODE_ROWMAJOR : 0)));
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								}
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							}
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cases that assign multiple basic-array elements with one glProgramUniform*v() (i.e. the count parameter is bigger than 1).
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const struct
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCase::Feature	arrayAssignMode;
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*				name;
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*				description;
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} arrayAssignGroups[] =
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ UniformCase::FEATURE_ARRAYASSIGN_FULL,			"basic_array_assign_full",		"Assign entire basic-type arrays per glProgramUniform*v() call"				},
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ UniformCase::FEATURE_ARRAYASSIGN_BLOCKS_OF_TWO,	"basic_array_assign_partial",	"Assign two elements of a basic-type array per glProgramUniform*v() call"	}
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int arrayAssignGroupNdx = 0; arrayAssignGroupNdx < DE_LENGTH_OF_ARRAY(arrayAssignGroups); arrayAssignGroupNdx++)
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			UniformCase::Feature	arrayAssignMode		= arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		groupName			= arrayAssignGroups[arrayAssignGroupNdx].name;
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const		groupDesc			= arrayAssignGroups[arrayAssignGroupNdx].description;
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* const curArrayAssignGroup = new TestCaseGroup(m_context, groupName, groupDesc);
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addChild(curArrayAssignGroup);
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const int basicArrayCollectionGroups[] = { UNIFORMCOLLECTIONS_BASIC_ARRAY, UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT, UNIFORMCOLLECTIONS_MULTIPLE_BASIC_ARRAY };
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int collectionGroupNdx = 0; collectionGroupNdx < DE_LENGTH_OF_ARRAY(basicArrayCollectionGroups); collectionGroupNdx++)
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const UniformCollectionGroup&	collectionGroup		= defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* const			collectionTestGroup	= new TestCaseGroup(m_context, collectionGroup.name.c_str(), "");
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				curArrayAssignGroup->addChild(collectionTestGroup);
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string								collName			= collectionCase.namePrefix;
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						collectionTestGroup->addChild(new UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			UniformAssignCase::CHECKMETHOD_GET_UNIFORM, UniformAssignCase::ASSIGNMETHOD_POINTER,
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																			arrayAssignMode));
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cases with unused uniforms.
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* const unusedUniformsGroup = new TestCaseGroup(m_context, "unused_uniforms", "Test with unused uniforms");
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(unusedUniformsGroup);
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const UniformCollectionGroup& collectionGroup = defaultUniformCollections[UNIFORMCOLLECTIONS_ARRAY_IN_STRUCT];
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int collectionNdx = 0; collectionNdx < (int)collectionGroup.cases.size(); collectionNdx++)
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const UniformCollectionCase&				collectionCase		= collectionGroup.cases[collectionNdx];
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string								collName			= collectionCase.namePrefix;
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const SharedPtr<const UniformCollection>&	uniformCollection	= collectionCase.uniformCollection;
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int shaderType = 0; shaderType < (int)CASESHADERTYPE_LAST; shaderType++)
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string name = collName + getCaseShaderTypeName((CaseShaderType)shaderType);
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				unusedUniformsGroup->addChild(new UniformAssignCase(m_context, name.c_str(), "", (CaseShaderType)shaderType, uniformCollection,
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	UniformAssignCase::CHECKMETHOD_GET_UNIFORM, UniformAssignCase::ASSIGNMETHOD_POINTER,
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	UniformCase::FEATURE_ARRAYUSAGE_ONLY_MIDDLE_INDEX | UniformCase::FEATURE_UNIFORMUSAGE_EVERY_OTHER));
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2098