Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Shader operators tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fShaderOperatorTests.hpp"
     25 #include "glsShaderRenderCase.hpp"
     26 #include "gluShaderUtil.hpp"
     27 #include "tcuStringTemplate.hpp"
     28 #include "tcuVectorUtil.hpp"
     29 #include "glwFunctions.hpp"
     30 #include "glwEnums.hpp"
     31 
     32 #include "deStringUtil.hpp"
     33 #include "deInt32.h"
     34 #include "deMemory.h"
     35 
     36 #include <map>
     37 #include <limits>
     38 
     39 using namespace tcu;
     40 using namespace glu;
     41 using namespace deqp::gls;
     42 
     43 using std::map;
     44 using std::pair;
     45 using std::vector;
     46 using std::string;
     47 using std::ostringstream;
     48 
     49 namespace deqp
     50 {
     51 namespace gles3
     52 {
     53 namespace Functional
     54 {
     55 
     56 #if defined(abs)
     57 #	undef abs
     58 #endif
     59 
     60 using de::min;
     61 using de::max;
     62 using de::clamp;
     63 
     64 // \note VS2013 gets confused without these
     65 using tcu::asinh;
     66 using tcu::acosh;
     67 using tcu::atanh;
     68 using tcu::exp2;
     69 using tcu::log2;
     70 using tcu::trunc;
     71 
     72 inline float abs		(float v)			{ return deFloatAbs(v); }
     73 
     74 inline bool logicalAnd	(bool a, bool b)	{ return (a && b); }
     75 inline bool logicalOr	(bool a, bool b)	{ return (a || b); }
     76 inline bool logicalXor	(bool a, bool b)	{ return (a != b); }
     77 
     78 // \note stdlib.h defines div() that is not compatible with the macros.
     79 template<typename T> inline T div (T a, T b) { return a / b; }
     80 
     81 template<typename T> inline T leftShift (T value, int amount) { return value << amount; }
     82 
     83 inline deUint32	rightShift (deUint32 value, int amount)		{ return value >> amount; }
     84 inline int		rightShift (int value, int amount)			{ return (value >> amount) | (value >= 0 ? 0 : ~(~0U >> amount)); } // \note Arithmetic shift.
     85 
     86 template<typename T, int Size> Vector<T, Size> leftShift (const Vector<T, Size>& value, const Vector<int, Size>& amount)
     87 {
     88 	Vector<T, Size> result;
     89 	for (int i = 0; i < Size; i++)
     90 		result[i] = leftShift(value[i], amount[i]);
     91 	return result;
     92 }
     93 
     94 template<typename T, int Size> Vector<T, Size> rightShift (const Vector<T, Size>& value, const Vector<int, Size>& amount)
     95 {
     96 	Vector<T, Size> result;
     97 	for (int i = 0; i < Size; i++)
     98 		result[i] = rightShift(value[i], amount[i]);
     99 	return result;
    100 }
    101 
    102 template<typename T, int Size> Vector<T, Size> leftShiftVecScalar	(const Vector<T, Size>& value, int amount) { return leftShift(value, Vector<int, Size>(amount)); }
    103 template<typename T, int Size> Vector<T, Size> rightShiftVecScalar	(const Vector<T, Size>& value, int amount) { return rightShift(value, Vector<int, Size>(amount)); }
    104 
    105 template<typename T, int Size>
    106 inline Vector<T, Size> minVecScalar (const Vector<T, Size>& v, T s)
    107 {
    108 	Vector<T, Size> res;
    109 	for (int i = 0; i < Size; i++)
    110 		res[i] = min(v[i], s);
    111 	return res;
    112 }
    113 
    114 template<typename T, int Size>
    115 inline Vector<T, Size> maxVecScalar (const Vector<T, Size>& v, T s)
    116 {
    117 	Vector<T, Size> res;
    118 	for (int i = 0; i < Size; i++)
    119 		res[i] = max(v[i], s);
    120 	return res;
    121 }
    122 
    123 template<typename T, int Size>
    124 inline Vector<T, Size> clampVecScalarScalar (const Vector<T, Size>& v, T s0, T s1)
    125 {
    126 	Vector<T, Size> res;
    127 	for (int i = 0; i < Size; i++)
    128 		res[i] = clamp(v[i], s0, s1);
    129 	return res;
    130 }
    131 
    132 template<typename T, int Size>
    133 inline Vector<T, Size> mixVecVecScalar (const Vector<T, Size>& v0, const Vector<T, Size>& v1, T s)
    134 {
    135 	Vector<T, Size> res;
    136 	for (int i = 0; i < Size; i++)
    137 		res[i] = mix(v0[i], v1[i], s);
    138 	return res;
    139 }
    140 
    141 template<typename T, int Size>
    142 inline Vector<T, Size> stepScalarVec (T s, const Vector<T, Size>& v)
    143 {
    144 	Vector<T, Size> res;
    145 	for (int i = 0; i < Size; i++)
    146 		res[i] = step(s, v[i]);
    147 	return res;
    148 }
    149 
    150 template<typename T, int Size>
    151 inline Vector<T, Size> smoothStepScalarScalarVec (T s0, T s1, const Vector<T, Size>& v)
    152 {
    153 	Vector<T, Size> res;
    154 	for (int i = 0; i < Size; i++)
    155 		res[i] = smoothStep(s0, s1, v[i]);
    156 	return res;
    157 }
    158 
    159 inline float	addOne (float v)	{ return v + 1.0f; };
    160 inline float	subOne (float v)	{ return v - 1.0f; };
    161 inline int		addOne (int v)		{ return v + 1; };
    162 inline int		subOne (int v)		{ return v - 1; };
    163 inline deUint32	addOne (deUint32 v)	{ return v + 1; };
    164 inline deUint32	subOne (deUint32 v)	{ return v - 1; };
    165 
    166 template<int Size> inline Vector<float, Size>		addOne (const Vector<float, Size>& v)		{ return v + 1.0f; };
    167 template<int Size> inline Vector<float, Size>		subOne (const Vector<float, Size>& v)		{ return v - 1.0f; };
    168 template<int Size> inline Vector<int, Size>			addOne (const Vector<int, Size>& v)			{ return v + 1; };
    169 template<int Size> inline Vector<int, Size>			subOne (const Vector<int, Size>& v)			{ return v - 1; };
    170 template<int Size> inline Vector<deUint32, Size>	addOne (const Vector<deUint32, Size>& v)	{ return v + 1U; };
    171 template<int Size> inline Vector<deUint32, Size>	subOne (const Vector<deUint32, Size>& v)	{ return (v.asInt() - 1).asUint(); };
    172 
    173 template<typename T> inline T selection	(bool cond, T a, T b)	{ return cond ? a : b; };
    174 
    175 // Vec-scalar and scalar-vec binary operators.
    176 
    177 // \note This one is done separately due to how the overloaded minus operator is implemented for vector-scalar operands.
    178 template<int Size>				inline Vector<deUint32, Size>	subVecScalar			(const Vector<deUint32, Size>& v, deUint32 s)	{ return (v.asInt() - (int)s).asUint(); };
    179 
    180 template<typename T, int Size>	inline Vector<T, Size>			addVecScalar			(const Vector<T, Size>& v, T s)					{ return v + s; };
    181 template<typename T, int Size>	inline Vector<T, Size>			subVecScalar			(const Vector<T, Size>& v, T s)					{ return v - s; };
    182 template<typename T, int Size>	inline Vector<T, Size>			mulVecScalar			(const Vector<T, Size>& v, T s)					{ return v * s; };
    183 template<typename T, int Size>	inline Vector<T, Size>			divVecScalar			(const Vector<T, Size>& v, T s)					{ return v / s; };
    184 template<typename T, int Size>	inline Vector<T, Size>			modVecScalar			(const Vector<T, Size>& v, T s)					{ return mod(v, Vector<T, Size>(s)); };
    185 template<typename T, int Size>	inline Vector<T, Size>			bitwiseAndVecScalar		(const Vector<T, Size>& v, T s)					{ return bitwiseAnd(v, Vector<T, Size>(s)); };
    186 template<typename T, int Size>	inline Vector<T, Size>			bitwiseOrVecScalar		(const Vector<T, Size>& v, T s)					{ return bitwiseOr(v, Vector<T, Size>(s)); };
    187 template<typename T, int Size>	inline Vector<T, Size>			bitwiseXorVecScalar		(const Vector<T, Size>& v, T s)					{ return bitwiseXor(v, Vector<T, Size>(s)); };
    188 
    189 template<typename T, int Size> inline Vector<T, Size>			addScalarVec			(T s, const Vector<T, Size>& v) 				{ return s + v; };
    190 template<typename T, int Size> inline Vector<T, Size>			subScalarVec			(T s, const Vector<T, Size>& v) 				{ return s - v; };
    191 template<typename T, int Size> inline Vector<T, Size>			mulScalarVec			(T s, const Vector<T, Size>& v) 				{ return s * v; };
    192 template<typename T, int Size> inline Vector<T, Size>			divScalarVec			(T s, const Vector<T, Size>& v) 				{ return s / v; };
    193 template<typename T, int Size> inline Vector<T, Size>			modScalarVec			(T s, const Vector<T, Size>& v)					{ return mod(Vector<T, Size>(s), v); };
    194 template<typename T, int Size> inline Vector<T, Size>			bitwiseAndScalarVec		(T s, const Vector<T, Size>& v)					{ return bitwiseAnd(Vector<T, Size>(s), v); };
    195 template<typename T, int Size> inline Vector<T, Size>			bitwiseOrScalarVec		(T s, const Vector<T, Size>& v)					{ return bitwiseOr(Vector<T, Size>(s), v); };
    196 template<typename T, int Size> inline Vector<T, Size>			bitwiseXorScalarVec		(T s, const Vector<T, Size>& v)					{ return bitwiseXor(Vector<T, Size>(s), v); };
    197 
    198 // Reference functions for specific sequence operations for the sequence operator tests.
    199 
    200 // Reference for expression "in0, in2 + in1, in1 + in0"
    201 inline Vec4		sequenceNoSideEffCase0 (const Vec4& in0, const Vec4& in1, const Vec4& in2)		{ DE_UNREF(in2); return in1 + in0; }
    202 // Reference for expression "in0, in2 + in1, in1 + in0"
    203 inline deUint32	sequenceNoSideEffCase1 (float in0, deUint32 in1, float in2)						{ DE_UNREF(in0); DE_UNREF(in2); return in1 + in1; }
    204 // Reference for expression "in0 && in1, in0, ivec2(vec2(in0) + in2)"
    205 inline IVec2	sequenceNoSideEffCase2 (bool in0, bool in1, const Vec2& in2)					{ DE_UNREF(in1); return IVec2((int)((float)in0 + in2.x()), (int)((float)in0 + in2.y())); }
    206 // Reference for expression "in0 + vec4(in1), in2, in1"
    207 inline IVec4	sequenceNoSideEffCase3 (const Vec4& in0, const IVec4& in1, const BVec4& in2)	{ DE_UNREF(in0); DE_UNREF(in2); return in1; }
    208 // Reference for expression "in0++, in1 = in0 + in2, in2 = in1"
    209 inline Vec4		sequenceSideEffCase0 (const Vec4& in0, const Vec4& in1, const Vec4& in2)		{ DE_UNREF(in1); return in0 + 1.0f + in2; }
    210 // Reference for expression "in1++, in0 = float(in1), in1 = uint(in0 + in2)"
    211 inline deUint32	sequenceSideEffCase1 (float in0, deUint32 in1, float in2)						{ DE_UNREF(in0); return (deUint32)(float(in1) + 1.0f + in2); }
    212 // Reference for expression "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)"
    213 inline IVec2	sequenceSideEffCase2 (bool in0, bool in1, const Vec2& in2)						{ DE_UNREF(in1); return (in2 + Vec2(1.0f) + Vec2((float)in0)).asInt(); }
    214 // Reference for expression "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++"
    215 inline IVec4	sequenceSideEffCase3 (const Vec4& in0, const IVec4& in1, const BVec4& in2)		{ return in1 + (in0 + Vec4((float)in2.x(), (float)in2.y(), (float)in2.z(), (float)in2.w())).asInt(); }
    216 
    217 // ShaderEvalFunc-type wrappers for the above functions.
    218 void evalSequenceNoSideEffCase0	(ShaderEvalContext& ctx) { ctx.color		= sequenceNoSideEffCase0		(ctx.in[0].swizzle(1, 2, 3, 0),	ctx.in[1].swizzle(3, 2, 1, 0),			ctx.in[2].swizzle(0, 3, 2, 1)); }
    219 void evalSequenceNoSideEffCase1	(ShaderEvalContext& ctx) { ctx.color.x()	= (float)sequenceNoSideEffCase1	(ctx.in[0].z(),					(deUint32)ctx.in[1].x(),				ctx.in[2].y()); }
    220 void evalSequenceNoSideEffCase2	(ShaderEvalContext& ctx) { ctx.color.yz()	= sequenceNoSideEffCase2		(ctx.in[0].z() > 0.0f,			ctx.in[1].x() > 0.0f,					ctx.in[2].swizzle(2, 1)).asFloat(); }
    221 void evalSequenceNoSideEffCase3	(ShaderEvalContext& ctx) { ctx.color		= sequenceNoSideEffCase3		(ctx.in[0].swizzle(1, 2, 3, 0),	ctx.in[1].swizzle(3, 2, 1, 0).asInt(),	greaterThan(ctx.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f))).asFloat(); }
    222 void evalSequenceSideEffCase0	(ShaderEvalContext& ctx) { ctx.color		= sequenceSideEffCase0			(ctx.in[0].swizzle(1, 2, 3, 0),	ctx.in[1].swizzle(3, 2, 1, 0),			ctx.in[2].swizzle(0, 3, 2, 1)); }
    223 void evalSequenceSideEffCase1	(ShaderEvalContext& ctx) { ctx.color.x()	= (float)sequenceSideEffCase1	(ctx.in[0].z(),					(deUint32)ctx.in[1].x(),				ctx.in[2].y()); }
    224 void evalSequenceSideEffCase2	(ShaderEvalContext& ctx) { ctx.color.yz()	= sequenceSideEffCase2			(ctx.in[0].z() > 0.0f,			ctx.in[1].x() > 0.0f,					ctx.in[2].swizzle(2, 1)).asFloat(); }
    225 void evalSequenceSideEffCase3	(ShaderEvalContext& ctx) { ctx.color		= sequenceSideEffCase3			(ctx.in[0].swizzle(1, 2, 3, 0),	ctx.in[1].swizzle(3, 2, 1, 0).asInt(),	greaterThan(ctx.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f))).asFloat(); }
    226 
    227 static string stringJoin (const vector<string>& elems, const string& delim)
    228 {
    229 	string result;
    230 	for (int i = 0; i < (int)elems.size(); i++)
    231 		result += (i > 0 ? delim : "") + elems[i];
    232 	return result;
    233 }
    234 
    235 static string twoValuedVec4 (const string& first, const string& second, const BVec4& firstMask)
    236 {
    237 	vector<string> elems(4);
    238 	for (int i = 0; i < 4; i++)
    239 		elems[i] = firstMask[i] ? first : second;
    240 
    241 	return "vec4(" + stringJoin(elems, ", ") + ")";
    242 }
    243 
    244 enum
    245 {
    246 	MAX_INPUTS = 3
    247 };
    248 
    249 enum PrecisionMask
    250 {
    251 	PRECMASK_NA				= 0,						//!< Precision not applicable (booleans)
    252 	PRECMASK_LOWP			= (1<<PRECISION_LOWP),
    253 	PRECMASK_MEDIUMP		= (1<<PRECISION_MEDIUMP),
    254 	PRECMASK_HIGHP			= (1<<PRECISION_HIGHP),
    255 
    256 	PRECMASK_LOWP_MEDIUMP	= PRECMASK_LOWP | PRECMASK_MEDIUMP,
    257 	PRECMASK_MEDIUMP_HIGHP	= PRECMASK_MEDIUMP | PRECMASK_HIGHP,
    258 	PRECMASK_ALL			= PRECMASK_LOWP | PRECMASK_MEDIUMP | PRECMASK_HIGHP
    259 };
    260 
    261 enum ValueType
    262 {
    263 	VALUE_NONE			= 0,
    264 	VALUE_FLOAT			= (1<<0),	// float scalar
    265 	VALUE_FLOAT_VEC		= (1<<1),	// float vector
    266 	VALUE_FLOAT_GENTYPE	= (1<<2),	// float scalar/vector
    267 	VALUE_VEC3			= (1<<3),	// vec3 only
    268 	VALUE_MATRIX		= (1<<4),	// matrix
    269 	VALUE_BOOL			= (1<<5),	// boolean scalar
    270 	VALUE_BOOL_VEC		= (1<<6),	// boolean vector
    271 	VALUE_BOOL_GENTYPE	= (1<<7),	// boolean scalar/vector
    272 	VALUE_INT			= (1<<8),	// int scalar
    273 	VALUE_INT_VEC		= (1<<9),	// int vector
    274 	VALUE_INT_GENTYPE	= (1<<10),	// int scalar/vector
    275 	VALUE_UINT			= (1<<11),	// uint scalar
    276 	VALUE_UINT_VEC		= (1<<12),	// uint vector
    277 	VALUE_UINT_GENTYPE	= (1<<13),	// uint scalar/vector
    278 
    279 	// Shorthands.
    280 	F				= VALUE_FLOAT,
    281 	FV				= VALUE_FLOAT_VEC,
    282 	GT				= VALUE_FLOAT_GENTYPE,
    283 	V3				= VALUE_VEC3,
    284 	M				= VALUE_MATRIX,
    285 	B				= VALUE_BOOL,
    286 	BV				= VALUE_BOOL_VEC,
    287 	BGT				= VALUE_BOOL_GENTYPE,
    288 	I				= VALUE_INT,
    289 	IV				= VALUE_INT_VEC,
    290 	IGT				= VALUE_INT_GENTYPE,
    291 	U				= VALUE_UINT,
    292 	UV				= VALUE_UINT_VEC,
    293 	UGT				= VALUE_UINT_GENTYPE
    294 };
    295 
    296 static inline bool isScalarType (ValueType type)
    297 {
    298 	return type == VALUE_FLOAT || type == VALUE_BOOL || type == VALUE_INT || type == VALUE_UINT;
    299 }
    300 
    301 static inline bool isFloatType (ValueType type)
    302 {
    303 	return (type & (VALUE_FLOAT | VALUE_FLOAT_VEC | VALUE_FLOAT_GENTYPE)) != 0;
    304 }
    305 
    306 static inline bool isIntType (ValueType type)
    307 {
    308 	return (type & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0;
    309 }
    310 
    311 static inline bool isUintType (ValueType type)
    312 {
    313 	return (type & (VALUE_UINT | VALUE_UINT_VEC | VALUE_UINT_GENTYPE)) != 0;
    314 }
    315 
    316 static inline bool isBoolType (ValueType type)
    317 {
    318 	return (type & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0;
    319 }
    320 
    321 static inline float getGLSLUintMaxAsFloat (const glw::Functions& gl, ShaderType shaderType, Precision uintPrecision)
    322 {
    323 	deUint32 intPrecisionGL;
    324 	deUint32 shaderTypeGL;
    325 
    326 	switch (uintPrecision)
    327 	{
    328 		case PRECISION_LOWP:		intPrecisionGL = GL_LOW_INT;		break;
    329 		case PRECISION_MEDIUMP:		intPrecisionGL = GL_MEDIUM_INT;		break;
    330 		case PRECISION_HIGHP:		intPrecisionGL = GL_HIGH_INT;		break;
    331 		default:
    332 			DE_ASSERT(false);
    333 			intPrecisionGL = 0;
    334 	}
    335 
    336 	switch (shaderType)
    337 	{
    338 		case SHADERTYPE_VERTEX:		shaderTypeGL = GL_VERTEX_SHADER;	break;
    339 		case SHADERTYPE_FRAGMENT:	shaderTypeGL = GL_FRAGMENT_SHADER;	break;
    340 		default:
    341 			DE_ASSERT(false);
    342 			shaderTypeGL = 0;
    343 	}
    344 
    345 	glw::GLint range[2]		= { -1, -1 };
    346 	glw::GLint precision	= -1;
    347 
    348 	gl.getShaderPrecisionFormat(shaderTypeGL, intPrecisionGL, &range[0], &precision);
    349 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderPrecisionFormat failed");
    350 
    351 	TCU_CHECK(de::inBounds(range[0], 8, 32));
    352 
    353 	const int numBitsInType = range[0] + 1;
    354 	return (float)((1ull << numBitsInType) - 1);
    355 }
    356 
    357 // Float scalar that can be either constant or a symbol that can be evaluated later.
    358 class FloatScalar
    359 {
    360 public:
    361 	enum Symbol
    362 	{
    363 		SYMBOL_LOWP_UINT_MAX = 0,
    364 		SYMBOL_MEDIUMP_UINT_MAX,
    365 
    366 		SYMBOL_LOWP_UINT_MAX_RECIPROCAL,
    367 		SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL,
    368 
    369 		SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX,
    370 		SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX,
    371 
    372 		SYMBOL_LAST
    373 	};
    374 
    375 	FloatScalar (float c)	: m_isConstant(true),	m_value(c) {}
    376 	FloatScalar (Symbol s)	: m_isConstant(false),	m_value(s) {}
    377 
    378 	float getValue (const glw::Functions& gl, ShaderType shaderType) const
    379 	{
    380 		if (m_isConstant)
    381 			return m_value.constant;
    382 		else
    383 		{
    384 			switch (m_value.symbol)
    385 			{
    386 				case SYMBOL_LOWP_UINT_MAX:								return getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_LOWP);
    387 				case SYMBOL_MEDIUMP_UINT_MAX:							return getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_MEDIUMP);
    388 
    389 				case SYMBOL_LOWP_UINT_MAX_RECIPROCAL:					return 1.0f / getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_LOWP);
    390 				case SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL:				return 1.0f / getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_MEDIUMP);
    391 
    392 				case SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX:		return 1.0f - (float)std::numeric_limits<deUint32>::max() / getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_LOWP);
    393 				case SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX:	return 1.0f - (float)std::numeric_limits<deUint32>::max() / getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_MEDIUMP);
    394 
    395 				default:
    396 					DE_ASSERT(false);
    397 					return 0.0f;
    398 			}
    399 		}
    400 	}
    401 
    402 private:
    403 	bool m_isConstant;
    404 
    405 	union ConstantOrSymbol
    406 	{
    407 		float	constant;
    408 		Symbol	symbol;
    409 
    410 		ConstantOrSymbol (float c)	: constant	(c) {}
    411 		ConstantOrSymbol (Symbol s)	: symbol	(s) {}
    412 	} m_value;
    413 };
    414 
    415 struct Value
    416 {
    417 	Value (ValueType valueType_, const FloatScalar& rangeMin_, const FloatScalar& rangeMax_)
    418 		: valueType	(valueType_)
    419 		, rangeMin	(rangeMin_)
    420 		, rangeMax	(rangeMax_)
    421 	{
    422 	}
    423 
    424 	ValueType		valueType;
    425 	FloatScalar		rangeMin;
    426 	FloatScalar		rangeMax;
    427 };
    428 
    429 enum OperationType
    430 {
    431 	FUNCTION = 0,
    432 	OPERATOR,
    433 	SIDE_EFFECT_OPERATOR // Test the side-effect (as opposed to the result) of a side-effect operator.
    434 };
    435 
    436 struct BuiltinFuncInfo
    437 {
    438 	BuiltinFuncInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_,
    439 					 Value input0_, Value input1_, Value input2_,
    440 					 const FloatScalar& resultScale_, const FloatScalar& resultBias_,
    441 					 deUint32 precisionMask_,
    442 					 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_,
    443 					 OperationType type_=FUNCTION, bool isUnaryPrefix_=true)
    444 		: caseName			(caseName_)
    445 		, shaderFuncName	(shaderFuncName_)
    446 		, outValue			(outValue_)
    447 		, input0			(input0_)
    448 		, input1			(input1_)
    449 		, input2			(input2_)
    450 		, resultScale		(resultScale_)
    451 		, resultBias		(resultBias_)
    452 		, referenceScale	(resultScale_)
    453 		, referenceBias		(resultBias_)
    454 		, precisionMask		(precisionMask_)
    455 		, evalFuncScalar	(evalFuncScalar_)
    456 		, evalFuncVec2		(evalFuncVec2_)
    457 		, evalFuncVec3		(evalFuncVec3_)
    458 		, evalFuncVec4		(evalFuncVec4_)
    459 		, type				(type_)
    460 		, isUnaryPrefix		(isUnaryPrefix_)
    461 	{
    462 	}
    463 
    464 	BuiltinFuncInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_,
    465 					 Value input0_, Value input1_, Value input2_,
    466 					 const FloatScalar& resultScale_, const FloatScalar& resultBias_, const FloatScalar& referenceScale_, const FloatScalar& referenceBias_,
    467 					 deUint32 precisionMask_,
    468 					 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_,
    469 					 OperationType type_=FUNCTION, bool isUnaryPrefix_=true)
    470 		: caseName			(caseName_)
    471 		, shaderFuncName	(shaderFuncName_)
    472 		, outValue			(outValue_)
    473 		, input0			(input0_)
    474 		, input1			(input1_)
    475 		, input2			(input2_)
    476 		, resultScale		(resultScale_)
    477 		, resultBias		(resultBias_)
    478 		, referenceScale	(referenceScale_)
    479 		, referenceBias		(referenceBias_)
    480 		, precisionMask		(precisionMask_)
    481 		, evalFuncScalar	(evalFuncScalar_)
    482 		, evalFuncVec2		(evalFuncVec2_)
    483 		, evalFuncVec3		(evalFuncVec3_)
    484 		, evalFuncVec4		(evalFuncVec4_)
    485 		, type				(type_)
    486 		, isUnaryPrefix		(isUnaryPrefix_)
    487 	{
    488 	}
    489 
    490 	const char*		caseName;			//!< Name of case.
    491 	const char*		shaderFuncName;		//!< Name in shading language.
    492 	ValueType		outValue;
    493 	Value			input0;
    494 	Value			input1;
    495 	Value			input2;
    496 	FloatScalar		resultScale;
    497 	FloatScalar		resultBias;
    498 	FloatScalar		referenceScale;
    499 	FloatScalar		referenceBias;
    500 	deUint32		precisionMask;
    501 	ShaderEvalFunc	evalFuncScalar;
    502 	ShaderEvalFunc	evalFuncVec2;
    503 	ShaderEvalFunc	evalFuncVec3;
    504 	ShaderEvalFunc	evalFuncVec4;
    505 	OperationType	type;
    506 	bool			isUnaryPrefix;		//!< Whether a unary operator is a prefix operator; redundant unless unary.
    507 };
    508 
    509 static inline BuiltinFuncInfo BuiltinOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, const FloatScalar& resultScale_, const FloatScalar& resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_)
    510 {
    511 	return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, OPERATOR);
    512 }
    513 
    514 static inline BuiltinFuncInfo BuiltinOperInfoSeparateRefScaleBias (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, const FloatScalar& resultScale_, const FloatScalar& resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_, const FloatScalar& referenceScale_, const FloatScalar& referenceBias_)
    515 {
    516 	return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, referenceScale_, referenceBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, OPERATOR);
    517 }
    518 
    519 // For postfix (unary) operators.
    520 static inline BuiltinFuncInfo BuiltinPostOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, const FloatScalar& resultScale_, const FloatScalar& resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_)
    521 {
    522 	return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, OPERATOR, false);
    523 }
    524 
    525 static inline BuiltinFuncInfo BuiltinSideEffOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, const FloatScalar& resultScale_, const FloatScalar& resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_)
    526 {
    527 	return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, SIDE_EFFECT_OPERATOR);
    528 }
    529 
    530 // For postfix (unary) operators, testing side-effect.
    531 static inline BuiltinFuncInfo BuiltinPostSideEffOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, const FloatScalar& resultScale_, const FloatScalar& resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_)
    532 {
    533 	return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, SIDE_EFFECT_OPERATOR, false);
    534 }
    535 
    536 // BuiltinFuncGroup
    537 
    538 struct BuiltinFuncGroup
    539 {
    540 						BuiltinFuncGroup	(const char* name_, const char* description_) : name(name_), description(description_) {}
    541 	BuiltinFuncGroup&	operator<<			(const BuiltinFuncInfo& info) { funcInfos.push_back(info); return *this; }
    542 
    543 	const char*						name;
    544 	const char*						description;
    545 	std::vector<BuiltinFuncInfo>	funcInfos;
    546 };
    547 
    548 static const char* s_inSwizzles[MAX_INPUTS][4] =
    549 {
    550 	{ "z", "wy", "zxy", "yzwx" },
    551 	{ "x", "yx", "yzx", "wzyx" },
    552 	{ "y", "zy", "wyz", "xwzy" }
    553 };
    554 
    555 static const char* s_outSwizzles[]	= { "x", "yz", "xyz", "xyzw" };
    556 
    557 static const BVec4 s_outSwizzleChannelMasks[] =
    558 {
    559 	BVec4(true,  false, false, false),
    560 	BVec4(false, true,  true,  false),
    561 	BVec4(true,  true,  true,  false),
    562 	BVec4(true,  true,  true,  true )
    563 };
    564 
    565 // OperatorShaderEvaluator
    566 
    567 class OperatorShaderEvaluator : public ShaderEvaluator
    568 {
    569 public:
    570 	OperatorShaderEvaluator (const glw::Functions& gl, ShaderType shaderType, ShaderEvalFunc evalFunc, const FloatScalar& scale, const FloatScalar& bias, int resultScalarSize)
    571 		: m_gl							(gl)
    572 		, m_shaderType					(shaderType)
    573 		, m_evalFunc					(evalFunc)
    574 		, m_scale						(scale)
    575 		, m_bias						(bias)
    576 		, m_resultScalarSize			(resultScalarSize)
    577 		, m_areScaleAndBiasEvaluated	(false)
    578 		, m_evaluatedScale				(-1.0f)
    579 		, m_evaluatedBias				(-1.0f)
    580 	{
    581 		DE_ASSERT(de::inRange(resultScalarSize, 1, 4));
    582 	}
    583 
    584 	virtual ~OperatorShaderEvaluator (void)
    585 	{
    586 	}
    587 
    588 	virtual void evaluate (ShaderEvalContext& ctx)
    589 	{
    590 		m_evalFunc(ctx);
    591 
    592 		if (!m_areScaleAndBiasEvaluated)
    593 		{
    594 			m_evaluatedScale	= m_scale.getValue(m_gl, m_shaderType);
    595 			m_evaluatedBias		= m_bias.getValue(m_gl, m_shaderType);
    596 			m_areScaleAndBiasEvaluated = true;
    597 		}
    598 
    599 		for (int i = 0; i < 4; i++)
    600 			if (s_outSwizzleChannelMasks[m_resultScalarSize-1][i])
    601 				ctx.color[i] = ctx.color[i] * m_evaluatedScale + m_evaluatedBias;
    602 	}
    603 
    604 private:
    605 	const glw::Functions&	m_gl;
    606 	ShaderType				m_shaderType;
    607 	ShaderEvalFunc			m_evalFunc;
    608 	FloatScalar				m_scale;
    609 	FloatScalar				m_bias;
    610 	int						m_resultScalarSize;
    611 
    612 	bool					m_areScaleAndBiasEvaluated;
    613 	float					m_evaluatedScale;
    614 	float					m_evaluatedBias;
    615 };
    616 
    617 // Concrete value.
    618 
    619 struct ShaderValue
    620 {
    621 	ShaderValue (DataType type_, const FloatScalar& rangeMin_, const FloatScalar& rangeMax_)
    622 		: type		(type_)
    623 		, rangeMin	(rangeMin_)
    624 		, rangeMax	(rangeMax_)
    625 	{
    626 	}
    627 
    628 	ShaderValue (void)
    629 		: type		(TYPE_LAST)
    630 		, rangeMin	(0.0f)
    631 		, rangeMax	(0.0f)
    632 	{
    633 	}
    634 
    635 	DataType		type;
    636 	FloatScalar		rangeMin;
    637 	FloatScalar		rangeMax;
    638 };
    639 
    640 struct ShaderDataSpec
    641 {
    642 	ShaderDataSpec (void)
    643 		: resultScale		(1.0f)
    644 		, resultBias		(0.0f)
    645 		, referenceScale	(1.0f)
    646 		, referenceBias		(0.0f)
    647 		, precision			(PRECISION_LAST)
    648 		, output			(TYPE_LAST)
    649 		, numInputs			(0)
    650 	{
    651 	}
    652 
    653 	FloatScalar		resultScale;
    654 	FloatScalar		resultBias;
    655 	FloatScalar		referenceScale;
    656 	FloatScalar		referenceBias;
    657 	Precision		precision;
    658 	DataType		output;
    659 	int				numInputs;
    660 	ShaderValue		inputs[MAX_INPUTS];
    661 };
    662 
    663 // ShaderOperatorCase
    664 
    665 class ShaderOperatorCase : public ShaderRenderCase
    666 {
    667 public:
    668 								ShaderOperatorCase		(Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const string& shaderOp, const ShaderDataSpec& spec);
    669 	virtual						~ShaderOperatorCase		(void);
    670 
    671 protected:
    672 	void						setupShaderData			(void);
    673 
    674 private:
    675 								ShaderOperatorCase		(const ShaderOperatorCase&);	// not allowed!
    676 	ShaderOperatorCase&			operator=				(const ShaderOperatorCase&);	// not allowed!
    677 
    678 	ShaderDataSpec				m_spec;
    679 	string						m_shaderOp;
    680 	OperatorShaderEvaluator		m_evaluator;
    681 };
    682 
    683 ShaderOperatorCase::ShaderOperatorCase (Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const string& shaderOp, const ShaderDataSpec& spec)
    684 	: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), caseName, description, isVertexCase, m_evaluator)
    685 	, m_spec			(spec)
    686 	, m_shaderOp		(shaderOp)
    687 	, m_evaluator		(m_renderCtx.getFunctions(), isVertexCase ? SHADERTYPE_VERTEX : SHADERTYPE_FRAGMENT, evalFunc, spec.referenceScale, spec.referenceBias, getDataTypeScalarSize(spec.output))
    688 {
    689 }
    690 
    691 void ShaderOperatorCase::setupShaderData (void)
    692 {
    693 	ShaderType		shaderType	= m_isVertexCase ? SHADERTYPE_VERTEX : SHADERTYPE_FRAGMENT;
    694 	const char*		precision	= m_spec.precision != PRECISION_LAST ? getPrecisionName(m_spec.precision) : DE_NULL;
    695 	const char*		inputPrecision[MAX_INPUTS];
    696 
    697 	ostringstream	vtx;
    698 	ostringstream	frag;
    699 	ostringstream&	op			= m_isVertexCase ? vtx : frag;
    700 
    701 	vtx << "#version 300 es\n";
    702 	frag << "#version 300 es\n";
    703 
    704 	// Compute precision for inputs.
    705 	for (int i = 0; i < m_spec.numInputs; i++)
    706 	{
    707 		bool		isBoolVal	= de::inRange<int>(m_spec.inputs[i].type, TYPE_BOOL, TYPE_BOOL_VEC4);
    708 		bool		isIntVal	= de::inRange<int>(m_spec.inputs[i].type, TYPE_INT, TYPE_INT_VEC4);
    709 		bool		isUintVal	= de::inRange<int>(m_spec.inputs[i].type, TYPE_UINT, TYPE_UINT_VEC4);
    710 		// \note Mediump interpolators are used for booleans, and highp for integers.
    711 		Precision	prec		= isBoolVal	? PRECISION_MEDIUMP
    712 								: isIntVal || isUintVal ? PRECISION_HIGHP
    713 								: m_spec.precision;
    714 		inputPrecision[i] = getPrecisionName(prec);
    715 	}
    716 
    717 	// Attributes.
    718 	vtx << "in highp vec4 a_position;\n";
    719 	for (int i = 0; i < m_spec.numInputs; i++)
    720 		vtx << "in " << inputPrecision[i] << " vec4 a_in" << i << ";\n";
    721 
    722 	// Color output.
    723 	frag << "layout(location = 0) out mediump vec4 o_color;\n";
    724 
    725 	if (m_isVertexCase)
    726 	{
    727 		vtx << "out mediump vec4 v_color;\n";
    728 		frag << "in mediump vec4 v_color;\n";
    729 	}
    730 	else
    731 	{
    732 		for (int i = 0; i < m_spec.numInputs; i++)
    733 		{
    734 			vtx << "out " << inputPrecision[i] << " vec4 v_in" << i << ";\n";
    735 			frag << "in " << inputPrecision[i] << " vec4 v_in" << i << ";\n";
    736 		}
    737 	}
    738 
    739 	vtx << "\n";
    740 	vtx << "void main()\n";
    741 	vtx << "{\n";
    742 	vtx << "	gl_Position = a_position;\n";
    743 
    744 	frag << "\n";
    745 	frag << "void main()\n";
    746 	frag << "{\n";
    747 
    748 	// Expression inputs.
    749 	string prefix = m_isVertexCase ? "a_" : "v_";
    750 	for (int i = 0; i < m_spec.numInputs; i++)
    751 	{
    752 		DataType		inType		= m_spec.inputs[i].type;
    753 		int				inSize		= getDataTypeScalarSize(inType);
    754 		bool			isInt		= de::inRange<int>(inType, TYPE_INT, TYPE_INT_VEC4);
    755 		bool			isUint		= de::inRange<int>(inType, TYPE_UINT, TYPE_UINT_VEC4);
    756 		bool			isBool		= de::inRange<int>(inType, TYPE_BOOL, TYPE_BOOL_VEC4);
    757 		const char*		typeName	= getDataTypeName(inType);
    758 		const char*		swizzle		= s_inSwizzles[i][inSize-1];
    759 
    760 		op << "\t";
    761 		if (precision && !isBool) op << precision << " ";
    762 
    763 		op << typeName << " in" << i << " = ";
    764 
    765 		if (isBool)
    766 		{
    767 			if (inSize == 1)	op << "(";
    768 			else				op << "greaterThan(";
    769 		}
    770 		else if (isInt || isUint)
    771 			op << typeName << "(";
    772 
    773 		op << prefix << "in" << i << "." << swizzle;
    774 
    775 		if (isBool)
    776 		{
    777 			if (inSize == 1)	op << " > 0.0)";
    778 			else				op << ", vec" << inSize << "(0.0))";
    779 		}
    780 		else if (isInt || isUint)
    781 			op << ")";
    782 
    783 		op << ";\n";
    784 	}
    785 
    786 	// Result variable.
    787 	{
    788 		const char* outTypeName = getDataTypeName(m_spec.output);
    789 		bool		isBoolOut	= de::inRange<int>(m_spec.output, TYPE_BOOL, TYPE_BOOL_VEC4);
    790 
    791 		op << "\t";
    792 		if (precision && !isBoolOut) op << precision << " ";
    793 		op << outTypeName << " res = " << outTypeName << "(0.0);\n\n";
    794 	}
    795 
    796 	// Expression.
    797 	op << "\t" << m_shaderOp << "\n\n";
    798 
    799 	// Convert to color.
    800 	bool	isResFloatVec	= de::inRange<int>(m_spec.output, TYPE_FLOAT, TYPE_FLOAT_VEC4);
    801 	int		outScalarSize	= getDataTypeScalarSize(m_spec.output);
    802 
    803 	op << "\thighp vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n";
    804 	op << "\tcolor." << s_outSwizzles[outScalarSize-1] << " = ";
    805 
    806 	if (!isResFloatVec && outScalarSize == 1)
    807 		op << "float(res)";
    808 	else if (!isResFloatVec)
    809 		op << "vec" << outScalarSize << "(res)";
    810 	else
    811 		op << "res";
    812 
    813 	op << ";\n";
    814 
    815 	// Scale & bias.
    816 	float	resultScale		= m_spec.resultScale.getValue(m_renderCtx.getFunctions(), shaderType);
    817 	float	resultBias		= m_spec.resultBias.getValue(m_renderCtx.getFunctions(), shaderType);
    818 	if ((resultScale != 1.0f) || (resultBias != 0.0f))
    819 	{
    820 		op << "\tcolor = color";
    821 		if (resultScale != 1.0f) op << " * " << twoValuedVec4(de::toString(resultScale),		"1.0", s_outSwizzleChannelMasks[outScalarSize-1]);
    822 		if (resultBias != 0.0f)  op << " + " << twoValuedVec4(de::floatToString(resultBias, 2),	"0.0", s_outSwizzleChannelMasks[outScalarSize-1]);
    823 		op << ";\n";
    824 	}
    825 
    826 	// ..
    827 	if (m_isVertexCase)
    828 	{
    829 		vtx << "	v_color = color;\n";
    830 		frag << "	o_color = v_color;\n";
    831 	}
    832 	else
    833 	{
    834 		for (int i = 0; i < m_spec.numInputs; i++)
    835 		vtx << "	v_in" << i << " = a_in" << i << ";\n";
    836 		frag << "	o_color = color;\n";
    837 	}
    838 
    839 	vtx << "}\n";
    840 	frag << "}\n";
    841 
    842 	m_vertShaderSource = vtx.str();
    843 	m_fragShaderSource = frag.str();
    844 
    845 	// Setup the user attributes.
    846 	m_userAttribTransforms.resize(m_spec.numInputs);
    847 	for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
    848 	{
    849 		const ShaderValue& v = m_spec.inputs[inputNdx];
    850 		DE_ASSERT(v.type != TYPE_LAST);
    851 
    852 		float rangeMin	= v.rangeMin.getValue(m_renderCtx.getFunctions(), shaderType);
    853 		float rangeMax	= v.rangeMax.getValue(m_renderCtx.getFunctions(), shaderType);
    854 		float scale		= rangeMax - rangeMin;
    855 		float minBias	= rangeMin;
    856 		float maxBias	= rangeMax;
    857 		Mat4  attribMatrix;
    858 
    859 		for (int rowNdx = 0; rowNdx < 4; rowNdx++)
    860 		{
    861 			Vec4 row;
    862 
    863 			switch ((rowNdx + inputNdx) % 4)
    864 			{
    865 				case 0:	row = Vec4(scale, 0.0f, 0.0f, minBias);		break;
    866 				case 1:	row = Vec4(0.0f, scale, 0.0f, minBias);		break;
    867 				case 2:	row = Vec4(-scale, 0.0f, 0.0f, maxBias);	break;
    868 				case 3:	row = Vec4(0.0f, -scale, 0.0f, maxBias);	break;
    869 				default: DE_ASSERT(false);
    870 			}
    871 
    872 			attribMatrix.setRow(rowNdx, row);
    873 		}
    874 
    875 		m_userAttribTransforms[inputNdx] = attribMatrix;
    876 	}
    877 }
    878 
    879 ShaderOperatorCase::~ShaderOperatorCase (void)
    880 {
    881 }
    882 
    883 // ShaderOperatorTests.
    884 
    885 ShaderOperatorTests::ShaderOperatorTests(Context& context)
    886 	: TestCaseGroup(context, "operator", "Operator tests.")
    887 {
    888 }
    889 
    890 ShaderOperatorTests::~ShaderOperatorTests (void)
    891 {
    892 }
    893 
    894 // Vector math functions.
    895 template<typename T> inline T nop (T f) { return f; }
    896 
    897 template <typename T, int Size>
    898 Vector<T, Size> nop (const Vector<T, Size>& v) { return v; }
    899 
    900 #define DECLARE_UNARY_GENTYPE_FUNCS(FUNC_NAME)																			\
    901 	void eval_##FUNC_NAME##_float	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(2)).x(); }		\
    902 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1)); }		\
    903 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1)); }	\
    904 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); }
    905 
    906 #define DECLARE_BINARY_GENTYPE_FUNCS(FUNC_NAME)																											\
    907 	void eval_##FUNC_NAME##_float	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(2),          c.in[1].swizzle(0)).x(); }			\
    908 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1),       c.in[1].swizzle(1, 0)); }			\
    909 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1),    c.in[1].swizzle(1, 2, 0)); }		\
    910 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); }
    911 
    912 #define DECLARE_TERNARY_GENTYPE_FUNCS(FUNC_NAME)																																	\
    913 	void eval_##FUNC_NAME##_float	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(2),          c.in[1].swizzle(0),          c.in[2].swizzle(1)).x(); }		\
    914 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1),       c.in[1].swizzle(1, 0),       c.in[2].swizzle(2, 1)); }			\
    915 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1),    c.in[1].swizzle(1, 2, 0),    c.in[2].swizzle(3, 1, 2)); }		\
    916 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0), c.in[2].swizzle(0, 3, 2, 1)); }
    917 
    918 #define DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME)																	\
    919 	void eval_##FUNC_NAME##_float	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(2)); }			\
    920 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(3, 1)); }		\
    921 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1)); }	\
    922 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); }
    923 
    924 #define DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME)																									\
    925 	void eval_##FUNC_NAME##_float	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(2),          c.in[1].swizzle(0)); }				\
    926 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(3, 1),       c.in[1].swizzle(1, 0)); }			\
    927 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1),    c.in[1].swizzle(1, 2, 0)); }		\
    928 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color.x()	= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); }
    929 
    930 #define DECLARE_BINARY_BOOL_FUNCS(FUNC_NAME)																		\
    931 	void eval_##FUNC_NAME##_bool	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); }
    932 
    933 #define DECLARE_UNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME)																											\
    934 	void eval_##FUNC_NAME##_bool	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME(c.in[0].z() > 0.0f); }										\
    935 	void eval_##FUNC_NAME##_bvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); }		\
    936 	void eval_##FUNC_NAME##_bvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); }		\
    937 	void eval_##FUNC_NAME##_bvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f))).asFloat(); }
    938 
    939 #define DECLARE_TERNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME)																																																					\
    940 	void eval_##FUNC_NAME##_bool	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME(c.in[0].z() > 0.0f,                            c.in[1].x() > 0.0f,                                   c.in[2].y() > 0.0f); }												\
    941 	void eval_##FUNC_NAME##_bvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)),       greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f)),       greaterThan(c.in[2].swizzle(2, 1), Vec2(0.0f))).asFloat(); }		\
    942 	void eval_##FUNC_NAME##_bvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)),    greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f)),    greaterThan(c.in[2].swizzle(3, 1, 2), Vec3(0.0f))).asFloat(); }		\
    943 	void eval_##FUNC_NAME##_bvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f)), greaterThan(c.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f))).asFloat(); }
    944 
    945 #define DECLARE_UNARY_INT_GENTYPE_FUNCS(FUNC_NAME)																						\
    946 	void eval_##FUNC_NAME##_int		(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((int)c.in[0].z()); }						\
    947 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asInt()).asFloat(); }		\
    948 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt()).asFloat(); }	\
    949 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt()).asFloat(); }
    950 
    951 #define DECLARE_BINARY_INT_GENTYPE_FUNCS(FUNC_NAME)																																\
    952 	void eval_##FUNC_NAME##_int		(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((int)c.in[0].z(),				(int)c.in[1].x()); }							\
    953 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asInt(),			c.in[1].swizzle(1, 0).asInt()).asFloat(); }		\
    954 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(),		c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); }	\
    955 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(),	c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); }
    956 
    957 #define DECLARE_UNARY_UINT_GENTYPE_FUNCS(FUNC_NAME)																						\
    958 	void eval_##FUNC_NAME##_uint	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((deUint32)c.in[0].z()); }				\
    959 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint()).asFloat(); }	\
    960 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint()).asFloat(); }	\
    961 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint()).asFloat(); }
    962 
    963 #define DECLARE_BINARY_UINT_GENTYPE_FUNCS(FUNC_NAME)																															\
    964 	void eval_##FUNC_NAME##_uint	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((deUint32)c.in[0].z(),			(deUint32)c.in[1].x()); }						\
    965 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),			c.in[1].swizzle(1, 0).asUint()).asFloat(); }	\
    966 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),		c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); }	\
    967 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(),	c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); }
    968 
    969 #define DECLARE_TERNARY_INT_GENTYPE_FUNCS(FUNC_NAME)																																								\
    970 	void eval_##FUNC_NAME##_int		(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((int)c.in[0].z(),				(int)c.in[1].x(),					(int)c.in[2].y()); }							\
    971 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asInt(),			c.in[1].swizzle(1, 0).asInt(),       c.in[2].swizzle(2, 1).asInt()).asFloat(); }	\
    972 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(),		c.in[1].swizzle(1, 2, 0).asInt(),    c.in[2].swizzle(3, 1, 2).asInt()).asFloat(); }	\
    973 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(),	c.in[1].swizzle(3, 2, 1, 0).asInt(), c.in[2].swizzle(0, 3, 2, 1).asInt()).asFloat(); }
    974 
    975 #define DECLARE_TERNARY_UINT_GENTYPE_FUNCS(FUNC_NAME)																																									\
    976 	void eval_##FUNC_NAME##_uint	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((deUint32)c.in[0].z(),			(deUint32)c.in[1].x(),					(deUint32)c.in[2].y()); }						\
    977 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),			c.in[1].swizzle(1, 0).asUint(),			c.in[2].swizzle(2, 1).asUint()).asFloat(); }	\
    978 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),		c.in[1].swizzle(1, 2, 0).asUint(),		c.in[2].swizzle(3, 1, 2).asUint()).asFloat(); }	\
    979 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(),	c.in[1].swizzle(3, 2, 1, 0).asUint(),	c.in[2].swizzle(0, 3, 2, 1).asUint()).asFloat(); }
    980 
    981 #define DECLARE_VEC_FLOAT_FUNCS(FUNC_NAME)																								\
    982 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1),			c.in[1].x()); } \
    983 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1),		c.in[1].x()); } \
    984 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0),	c.in[1].x()); }
    985 
    986 #define DECLARE_VEC_FLOAT_FLOAT_FUNCS(FUNC_NAME) \
    987 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1),			c.in[1].x(), c.in[2].y()); } \
    988 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1),		c.in[1].x(), c.in[2].y()); } \
    989 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0),	c.in[1].x(), c.in[2].y()); }
    990 
    991 #define DECLARE_VEC_VEC_FLOAT_FUNCS(FUNC_NAME) \
    992 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1),			c.in[1].swizzle(1, 0),			c.in[2].y()); } \
    993 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1),		c.in[1].swizzle(1, 2, 0),		c.in[2].y()); } \
    994 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0),	c.in[1].swizzle(3, 2, 1, 0),	c.in[2].y()); }
    995 
    996 #define DECLARE_FLOAT_FLOAT_VEC_FUNCS(FUNC_NAME) \
    997 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(2, 1)); }			\
    998 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(3, 1, 2)); }		\
    999 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(0, 3, 2, 1)); }
   1000 
   1001 #define DECLARE_FLOAT_VEC_FUNCS(FUNC_NAME)																												\
   1002 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].z(),					c.in[1].swizzle(1, 0)); }		\
   1003 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].z(),					c.in[1].swizzle(1, 2, 0)); }	\
   1004 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].z(),					c.in[1].swizzle(3, 2, 1, 0)); }
   1005 
   1006 #define DECLARE_IVEC_INT_FUNCS(FUNC_NAME)																														\
   1007 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asInt(),			(int)c.in[1].x()).asFloat(); }	\
   1008 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(),		(int)c.in[1].x()).asFloat(); }	\
   1009 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(),	(int)c.in[1].x()).asFloat(); }
   1010 
   1011 #define DECLARE_IVEC_INT_INT_FUNCS(FUNC_NAME) \
   1012 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asInt(),			(int)c.in[1].x(), (int)c.in[2].y()).asFloat(); } \
   1013 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(),		(int)c.in[1].x(), (int)c.in[2].y()).asFloat(); } \
   1014 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(),	(int)c.in[1].x(), (int)c.in[2].y()).asFloat(); }
   1015 
   1016 #define DECLARE_INT_IVEC_FUNCS(FUNC_NAME)																																	\
   1017 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME((int)c.in[0].z(),					c.in[1].swizzle(1, 0).asInt()).asFloat(); }		\
   1018 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME((int)c.in[0].z(),					c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); }	\
   1019 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME((int)c.in[0].z(),					c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); }
   1020 
   1021 #define DECLARE_UVEC_UINT_FUNCS(FUNC_NAME)																															\
   1022 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),			(deUint32)c.in[1].x()).asFloat(); }	\
   1023 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),		(deUint32)c.in[1].x()).asFloat(); }	\
   1024 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(),	(deUint32)c.in[1].x()).asFloat(); }
   1025 
   1026 #define DECLARE_UVEC_UINT_UINT_FUNCS(FUNC_NAME) \
   1027 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),			(deUint32)c.in[1].x(), (deUint32)c.in[2].y()).asFloat(); } \
   1028 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),		(deUint32)c.in[1].x(), (deUint32)c.in[2].y()).asFloat(); } \
   1029 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(),	(deUint32)c.in[1].x(), (deUint32)c.in[2].y()).asFloat(); }
   1030 
   1031 #define DECLARE_UINT_UVEC_FUNCS(FUNC_NAME)																																		\
   1032 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME((deUint32)c.in[0].z(),					c.in[1].swizzle(1, 0).asUint()).asFloat(); }	\
   1033 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME((deUint32)c.in[0].z(),					c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); }	\
   1034 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME((deUint32)c.in[0].z(),					c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); }
   1035 
   1036 #define DECLARE_BINARY_INT_VEC_FUNCS(FUNC_NAME)																																	\
   1037 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asInt(),			c.in[1].swizzle(1, 0).asInt()).asFloat(); }		\
   1038 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(),		c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); }	\
   1039 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(),	c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); }
   1040 
   1041 #define DECLARE_BINARY_UINT_VEC_FUNCS(FUNC_NAME)																																\
   1042 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),			c.in[1].swizzle(1, 0).asUint()).asFloat(); }	\
   1043 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),		c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); }	\
   1044 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(),	c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); }
   1045 
   1046 #define DECLARE_UINT_INT_GENTYPE_FUNCS(FUNC_NAME)																																\
   1047 	void eval_##FUNC_NAME##_uint	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((deUint32)c.in[0].z(),			(int)c.in[1].x()); }							\
   1048 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),			c.in[1].swizzle(1, 0).asInt()).asFloat(); }		\
   1049 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),		c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); }	\
   1050 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(),	c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); }
   1051 
   1052 #define DECLARE_UVEC_INT_FUNCS(FUNC_NAME)																														\
   1053 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),			(int)c.in[1].x()).asFloat(); }	\
   1054 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),		(int)c.in[1].x()).asFloat(); }	\
   1055 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(),	(int)c.in[1].x()).asFloat(); }
   1056 
   1057 
   1058 // Operators.
   1059 
   1060 DECLARE_UNARY_GENTYPE_FUNCS(nop)
   1061 DECLARE_UNARY_GENTYPE_FUNCS(negate)
   1062 DECLARE_UNARY_GENTYPE_FUNCS(addOne)
   1063 DECLARE_UNARY_GENTYPE_FUNCS(subOne)
   1064 DECLARE_BINARY_GENTYPE_FUNCS(add)
   1065 DECLARE_BINARY_GENTYPE_FUNCS(sub)
   1066 DECLARE_BINARY_GENTYPE_FUNCS(mul)
   1067 DECLARE_BINARY_GENTYPE_FUNCS(div)
   1068 
   1069 void eval_selection_float	(ShaderEvalContext& c) { c.color.x()	= selection(c.in[0].z() > 0.0f,		c.in[1].x(),					c.in[2].y()); }
   1070 void eval_selection_vec2	(ShaderEvalContext& c) { c.color.yz()	= selection(c.in[0].z() > 0.0f,		c.in[1].swizzle(1, 0),			c.in[2].swizzle(2, 1)); }
   1071 void eval_selection_vec3	(ShaderEvalContext& c) { c.color.xyz()	= selection(c.in[0].z() > 0.0f,		c.in[1].swizzle(1, 2, 0),		c.in[2].swizzle(3, 1, 2)); }
   1072 void eval_selection_vec4	(ShaderEvalContext& c) { c.color		= selection(c.in[0].z() > 0.0f,		c.in[1].swizzle(3, 2, 1, 0),	c.in[2].swizzle(0, 3, 2, 1)); }
   1073 
   1074 DECLARE_UNARY_INT_GENTYPE_FUNCS(nop)
   1075 DECLARE_UNARY_INT_GENTYPE_FUNCS(negate)
   1076 DECLARE_UNARY_INT_GENTYPE_FUNCS(addOne)
   1077 DECLARE_UNARY_INT_GENTYPE_FUNCS(subOne)
   1078 DECLARE_UNARY_INT_GENTYPE_FUNCS(bitwiseNot)
   1079 DECLARE_BINARY_INT_GENTYPE_FUNCS(add)
   1080 DECLARE_BINARY_INT_GENTYPE_FUNCS(sub)
   1081 DECLARE_BINARY_INT_GENTYPE_FUNCS(mul)
   1082 DECLARE_BINARY_INT_GENTYPE_FUNCS(div)
   1083 DECLARE_BINARY_INT_GENTYPE_FUNCS(mod)
   1084 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseAnd)
   1085 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseOr)
   1086 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseXor)
   1087 
   1088 void eval_leftShift_int		(ShaderEvalContext& c) { c.color.x()	= (float)leftShift((int)c.in[0].z(),				(int)c.in[1].x()); }
   1089 DECLARE_BINARY_INT_VEC_FUNCS(leftShift)
   1090 void eval_rightShift_int	(ShaderEvalContext& c) { c.color.x()	= (float)rightShift((int)c.in[0].z(),				(int)c.in[1].x()); }
   1091 DECLARE_BINARY_INT_VEC_FUNCS(rightShift)
   1092 DECLARE_IVEC_INT_FUNCS(leftShiftVecScalar)
   1093 DECLARE_IVEC_INT_FUNCS(rightShiftVecScalar)
   1094 
   1095 void eval_selection_int		(ShaderEvalContext& c) { c.color.x()	= (float)selection(c.in[0].z() > 0.0f,	(int)c.in[1].x(),						(int)c.in[2].y()); }
   1096 void eval_selection_ivec2	(ShaderEvalContext& c) { c.color.yz()	= selection(c.in[0].z() > 0.0f,			c.in[1].swizzle(1, 0).asInt(),			c.in[2].swizzle(2, 1).asInt()).asFloat(); }
   1097 void eval_selection_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= selection(c.in[0].z() > 0.0f,			c.in[1].swizzle(1, 2, 0).asInt(),		c.in[2].swizzle(3, 1, 2).asInt()).asFloat(); }
   1098 void eval_selection_ivec4	(ShaderEvalContext& c) { c.color		= selection(c.in[0].z() > 0.0f,			c.in[1].swizzle(3, 2, 1, 0).asInt(),	c.in[2].swizzle(0, 3, 2, 1).asInt()).asFloat(); }
   1099 
   1100 DECLARE_UNARY_UINT_GENTYPE_FUNCS(nop)
   1101 DECLARE_UNARY_UINT_GENTYPE_FUNCS(negate)
   1102 DECLARE_UNARY_UINT_GENTYPE_FUNCS(bitwiseNot)
   1103 DECLARE_UNARY_UINT_GENTYPE_FUNCS(addOne)
   1104 DECLARE_UNARY_UINT_GENTYPE_FUNCS(subOne)
   1105 DECLARE_BINARY_UINT_GENTYPE_FUNCS(add)
   1106 DECLARE_BINARY_UINT_GENTYPE_FUNCS(sub)
   1107 DECLARE_BINARY_UINT_GENTYPE_FUNCS(mul)
   1108 DECLARE_BINARY_UINT_GENTYPE_FUNCS(div)
   1109 DECLARE_BINARY_UINT_GENTYPE_FUNCS(mod)
   1110 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseAnd)
   1111 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseOr)
   1112 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseXor)
   1113 
   1114 DECLARE_UINT_INT_GENTYPE_FUNCS(leftShift)
   1115 DECLARE_UINT_INT_GENTYPE_FUNCS(rightShift)
   1116 DECLARE_UVEC_INT_FUNCS(leftShiftVecScalar)
   1117 DECLARE_UVEC_INT_FUNCS(rightShiftVecScalar)
   1118 
   1119 void eval_selection_uint	(ShaderEvalContext& c) { c.color.x()	= (float)selection(c.in[0].z() > 0.0f,	(deUint32)c.in[1].x(),					(deUint32)c.in[2].y()); }
   1120 void eval_selection_uvec2	(ShaderEvalContext& c) { c.color.yz()	= selection(c.in[0].z() > 0.0f,			c.in[1].swizzle(1, 0).asUint(),			c.in[2].swizzle(2, 1).asUint()).asFloat(); }
   1121 void eval_selection_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= selection(c.in[0].z() > 0.0f,			c.in[1].swizzle(1, 2, 0).asUint(),		c.in[2].swizzle(3, 1, 2).asUint()).asFloat(); }
   1122 void eval_selection_uvec4	(ShaderEvalContext& c) { c.color		= selection(c.in[0].z() > 0.0f,			c.in[1].swizzle(3, 2, 1, 0).asUint(),	c.in[2].swizzle(0, 3, 2, 1).asUint()).asFloat(); }
   1123 
   1124 DECLARE_UNARY_BOOL_GENTYPE_FUNCS(boolNot)
   1125 DECLARE_BINARY_BOOL_FUNCS(logicalAnd)
   1126 DECLARE_BINARY_BOOL_FUNCS(logicalOr)
   1127 DECLARE_BINARY_BOOL_FUNCS(logicalXor)
   1128 
   1129 void eval_selection_bool	(ShaderEvalContext& c) { c.color.x()	= (float)selection(c.in[0].z() > 0.0f,	c.in[1].x() > 0.0f,														c.in[2].y() > 0.0f); }
   1130 void eval_selection_bvec2	(ShaderEvalContext& c) { c.color.yz()	= selection(c.in[0].z() > 0.0f,			greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f, 0.0f)),					greaterThan(c.in[2].swizzle(2, 1), Vec2(0.0f, 0.0f))).asFloat(); }
   1131 void eval_selection_bvec3	(ShaderEvalContext& c) { c.color.xyz()	= selection(c.in[0].z() > 0.0f,			greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f, 0.0f, 0.0f)),			greaterThan(c.in[2].swizzle(3, 1, 2), Vec3(0.0f, 0.0f, 0.0f))).asFloat(); }
   1132 void eval_selection_bvec4	(ShaderEvalContext& c) { c.color		= selection(c.in[0].z() > 0.0f,			greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f, 0.0f, 0.0f, 0.0f)),	greaterThan(c.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f))).asFloat(); }
   1133 
   1134 DECLARE_VEC_FLOAT_FUNCS(addVecScalar)
   1135 DECLARE_VEC_FLOAT_FUNCS(subVecScalar)
   1136 DECLARE_VEC_FLOAT_FUNCS(mulVecScalar)
   1137 DECLARE_VEC_FLOAT_FUNCS(divVecScalar)
   1138 
   1139 DECLARE_FLOAT_VEC_FUNCS(addScalarVec)
   1140 DECLARE_FLOAT_VEC_FUNCS(subScalarVec)
   1141 DECLARE_FLOAT_VEC_FUNCS(mulScalarVec)
   1142 DECLARE_FLOAT_VEC_FUNCS(divScalarVec)
   1143 
   1144 DECLARE_IVEC_INT_FUNCS(addVecScalar)
   1145 DECLARE_IVEC_INT_FUNCS(subVecScalar)
   1146 DECLARE_IVEC_INT_FUNCS(mulVecScalar)
   1147 DECLARE_IVEC_INT_FUNCS(divVecScalar)
   1148 DECLARE_IVEC_INT_FUNCS(modVecScalar)
   1149 DECLARE_IVEC_INT_FUNCS(bitwiseAndVecScalar)
   1150 DECLARE_IVEC_INT_FUNCS(bitwiseOrVecScalar)
   1151 DECLARE_IVEC_INT_FUNCS(bitwiseXorVecScalar)
   1152 
   1153 DECLARE_INT_IVEC_FUNCS(addScalarVec)
   1154 DECLARE_INT_IVEC_FUNCS(subScalarVec)
   1155 DECLARE_INT_IVEC_FUNCS(mulScalarVec)
   1156 DECLARE_INT_IVEC_FUNCS(divScalarVec)
   1157 DECLARE_INT_IVEC_FUNCS(modScalarVec)
   1158 DECLARE_INT_IVEC_FUNCS(bitwiseAndScalarVec)
   1159 DECLARE_INT_IVEC_FUNCS(bitwiseOrScalarVec)
   1160 DECLARE_INT_IVEC_FUNCS(bitwiseXorScalarVec)
   1161 
   1162 DECLARE_UVEC_UINT_FUNCS(addVecScalar)
   1163 DECLARE_UVEC_UINT_FUNCS(subVecScalar)
   1164 DECLARE_UVEC_UINT_FUNCS(mulVecScalar)
   1165 DECLARE_UVEC_UINT_FUNCS(divVecScalar)
   1166 DECLARE_UVEC_UINT_FUNCS(modVecScalar)
   1167 DECLARE_UVEC_UINT_FUNCS(bitwiseAndVecScalar)
   1168 DECLARE_UVEC_UINT_FUNCS(bitwiseOrVecScalar)
   1169 DECLARE_UVEC_UINT_FUNCS(bitwiseXorVecScalar)
   1170 
   1171 DECLARE_UINT_UVEC_FUNCS(addScalarVec)
   1172 DECLARE_UINT_UVEC_FUNCS(subScalarVec)
   1173 DECLARE_UINT_UVEC_FUNCS(mulScalarVec)
   1174 DECLARE_UINT_UVEC_FUNCS(divScalarVec)
   1175 DECLARE_UINT_UVEC_FUNCS(modScalarVec)
   1176 DECLARE_UINT_UVEC_FUNCS(bitwiseAndScalarVec)
   1177 DECLARE_UINT_UVEC_FUNCS(bitwiseOrScalarVec)
   1178 DECLARE_UINT_UVEC_FUNCS(bitwiseXorScalarVec)
   1179 
   1180 // Built-in functions.
   1181 
   1182 DECLARE_UNARY_GENTYPE_FUNCS(radians)
   1183 DECLARE_UNARY_GENTYPE_FUNCS(degrees)
   1184 DECLARE_UNARY_GENTYPE_FUNCS(sin)
   1185 DECLARE_UNARY_GENTYPE_FUNCS(cos)
   1186 DECLARE_UNARY_GENTYPE_FUNCS(tan)
   1187 DECLARE_UNARY_GENTYPE_FUNCS(asin)
   1188 DECLARE_UNARY_GENTYPE_FUNCS(acos)
   1189 DECLARE_UNARY_GENTYPE_FUNCS(atan)
   1190 DECLARE_BINARY_GENTYPE_FUNCS(atan2)
   1191 DECLARE_UNARY_GENTYPE_FUNCS(sinh)
   1192 DECLARE_UNARY_GENTYPE_FUNCS(cosh)
   1193 DECLARE_UNARY_GENTYPE_FUNCS(tanh)
   1194 DECLARE_UNARY_GENTYPE_FUNCS(asinh)
   1195 DECLARE_UNARY_GENTYPE_FUNCS(acosh)
   1196 DECLARE_UNARY_GENTYPE_FUNCS(atanh)
   1197 
   1198 DECLARE_BINARY_GENTYPE_FUNCS(pow)
   1199 DECLARE_UNARY_GENTYPE_FUNCS(exp)
   1200 DECLARE_UNARY_GENTYPE_FUNCS(log)
   1201 DECLARE_UNARY_GENTYPE_FUNCS(exp2)
   1202 DECLARE_UNARY_GENTYPE_FUNCS(log2)
   1203 DECLARE_UNARY_GENTYPE_FUNCS(sqrt)
   1204 DECLARE_UNARY_GENTYPE_FUNCS(inverseSqrt)
   1205 
   1206 DECLARE_UNARY_GENTYPE_FUNCS(abs)
   1207 DECLARE_UNARY_GENTYPE_FUNCS(sign)
   1208 DECLARE_UNARY_GENTYPE_FUNCS(floor)
   1209 DECLARE_UNARY_GENTYPE_FUNCS(trunc)
   1210 DECLARE_UNARY_GENTYPE_FUNCS(roundToEven)
   1211 DECLARE_UNARY_GENTYPE_FUNCS(ceil)
   1212 DECLARE_UNARY_GENTYPE_FUNCS(fract)
   1213 DECLARE_BINARY_GENTYPE_FUNCS(mod)
   1214 DECLARE_VEC_FLOAT_FUNCS(modVecScalar)
   1215 DECLARE_BINARY_GENTYPE_FUNCS(min)
   1216 DECLARE_VEC_FLOAT_FUNCS(minVecScalar)
   1217 DECLARE_BINARY_INT_GENTYPE_FUNCS(min)
   1218 DECLARE_IVEC_INT_FUNCS(minVecScalar)
   1219 DECLARE_BINARY_UINT_GENTYPE_FUNCS(min)
   1220 DECLARE_UVEC_UINT_FUNCS(minVecScalar)
   1221 DECLARE_BINARY_GENTYPE_FUNCS(max)
   1222 DECLARE_VEC_FLOAT_FUNCS(maxVecScalar)
   1223 DECLARE_BINARY_INT_GENTYPE_FUNCS(max)
   1224 DECLARE_IVEC_INT_FUNCS(maxVecScalar)
   1225 DECLARE_BINARY_UINT_GENTYPE_FUNCS(max)
   1226 DECLARE_UVEC_UINT_FUNCS(maxVecScalar)
   1227 DECLARE_TERNARY_GENTYPE_FUNCS(clamp)
   1228 DECLARE_VEC_FLOAT_FLOAT_FUNCS(clampVecScalarScalar)
   1229 DECLARE_TERNARY_INT_GENTYPE_FUNCS(clamp)
   1230 DECLARE_IVEC_INT_INT_FUNCS(clampVecScalarScalar)
   1231 DECLARE_TERNARY_UINT_GENTYPE_FUNCS(clamp)
   1232 DECLARE_UVEC_UINT_UINT_FUNCS(clampVecScalarScalar)
   1233 DECLARE_TERNARY_GENTYPE_FUNCS(mix)
   1234 DECLARE_VEC_VEC_FLOAT_FUNCS(mixVecVecScalar)
   1235 DECLARE_BINARY_GENTYPE_FUNCS(step)
   1236 DECLARE_FLOAT_VEC_FUNCS(stepScalarVec)
   1237 DECLARE_TERNARY_GENTYPE_FUNCS(smoothStep)
   1238 DECLARE_FLOAT_FLOAT_VEC_FUNCS(smoothStepScalarScalarVec)
   1239 
   1240 DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(length)
   1241 DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(distance)
   1242 DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(dot)
   1243 void eval_cross_vec3 (ShaderEvalContext& c) { c.color.xyz()	= cross(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); }
   1244 
   1245 DECLARE_UNARY_GENTYPE_FUNCS(normalize)
   1246 DECLARE_TERNARY_GENTYPE_FUNCS(faceForward)
   1247 DECLARE_BINARY_GENTYPE_FUNCS(reflect)
   1248 
   1249 void eval_refract_float	(ShaderEvalContext& c) { c.color.x()	= refract(c.in[0].z(),                 c.in[1].x(),                 c.in[2].y()); }
   1250 void eval_refract_vec2	(ShaderEvalContext& c) { c.color.yz()	= refract(c.in[0].swizzle(3, 1),       c.in[1].swizzle(1, 0),       c.in[2].y()); }
   1251 void eval_refract_vec3	(ShaderEvalContext& c) { c.color.xyz()	= refract(c.in[0].swizzle(2, 0, 1),    c.in[1].swizzle(1, 2, 0),    c.in[2].y()); }
   1252 void eval_refract_vec4	(ShaderEvalContext& c) { c.color		= refract(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0), c.in[2].y()); }
   1253 
   1254 // Compare functions.
   1255 
   1256 #define DECLARE_FLOAT_COMPARE_FUNCS(FUNC_NAME)																											\
   1257 	void eval_##FUNC_NAME##_float	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].z(),          c.in[1].x()); }						\
   1258 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(3, 1),       c.in[1].swizzle(1, 0)); }		\
   1259 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(2, 0, 1),    c.in[1].swizzle(1, 2, 0)); }	\
   1260 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); }
   1261 
   1262 #define DECLARE_FLOAT_CWISE_COMPARE_FUNCS(FUNC_NAME)																											\
   1263 	void eval_##FUNC_NAME##_float	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME(c.in[0].z(),          c.in[1].x()); }							\
   1264 	void eval_##FUNC_NAME##_vec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1),       c.in[1].swizzle(1, 0)).asFloat(); }		\
   1265 	void eval_##FUNC_NAME##_vec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1),    c.in[1].swizzle(1, 2, 0)).asFloat(); }		\
   1266 	void eval_##FUNC_NAME##_vec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)).asFloat(); }
   1267 
   1268 #define DECLARE_INT_COMPARE_FUNCS(FUNC_NAME)																																	\
   1269 	void eval_##FUNC_NAME##_int		(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); }									\
   1270 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].swizzle(3, 1)),       chopToInt(c.in[1].swizzle(1, 0))); }		\
   1271 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].swizzle(2, 0, 1)),    chopToInt(c.in[1].swizzle(1, 2, 0))); }		\
   1272 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].swizzle(1, 2, 3, 0)), chopToInt(c.in[1].swizzle(3, 2, 1, 0))); }
   1273 
   1274 #define DECLARE_INT_CWISE_COMPARE_FUNCS(FUNC_NAME)																																	\
   1275 	void eval_##FUNC_NAME##_int		(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); }									\
   1276 	void eval_##FUNC_NAME##_ivec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(chopToInt(c.in[0].swizzle(3, 1)),       chopToInt(c.in[1].swizzle(1, 0))).asFloat(); }		\
   1277 	void eval_##FUNC_NAME##_ivec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(chopToInt(c.in[0].swizzle(2, 0, 1)),    chopToInt(c.in[1].swizzle(1, 2, 0))).asFloat(); }	\
   1278 	void eval_##FUNC_NAME##_ivec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(chopToInt(c.in[0].swizzle(1, 2, 3, 0)), chopToInt(c.in[1].swizzle(3, 2, 1, 0))).asFloat(); }
   1279 
   1280 #define DECLARE_UINT_COMPARE_FUNCS(FUNC_NAME)																																\
   1281 	void eval_##FUNC_NAME##_uint	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME((deUint32)c.in[0].z(), (deUint32)c.in[1].x()); }								\
   1282 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),       c.in[1].swizzle(1, 0).asUint()); }		\
   1283 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),    c.in[1].swizzle(1, 2, 0).asUint()); }		\
   1284 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()); }
   1285 
   1286 #define DECLARE_UINT_CWISE_COMPARE_FUNCS(FUNC_NAME)																																\
   1287 	void eval_##FUNC_NAME##_uint	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME((deUint32)c.in[0].z(), (deUint32)c.in[1].x()); }									\
   1288 	void eval_##FUNC_NAME##_uvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(c.in[0].swizzle(3, 1).asUint(),       c.in[1].swizzle(1, 0).asUint()).asFloat(); }		\
   1289 	void eval_##FUNC_NAME##_uvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(),    c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); }	\
   1290 	void eval_##FUNC_NAME##_uvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); }
   1291 
   1292 #define DECLARE_BOOL_COMPARE_FUNCS(FUNC_NAME)																																								\
   1293 	void eval_##FUNC_NAME##_bool	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); }																		\
   1294 	void eval_##FUNC_NAME##_bvec2	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)),       greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f))); }		\
   1295 	void eval_##FUNC_NAME##_bvec3	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)),    greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f))); }		\
   1296 	void eval_##FUNC_NAME##_bvec4	(ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f))); }
   1297 
   1298 #define DECLARE_BOOL_CWISE_COMPARE_FUNCS(FUNC_NAME)																																								\
   1299 	void eval_##FUNC_NAME##_bool	(ShaderEvalContext& c) { c.color.x()	= (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); }																		\
   1300 	void eval_##FUNC_NAME##_bvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)),       greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f))).asFloat(); }		\
   1301 	void eval_##FUNC_NAME##_bvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)),    greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f))).asFloat(); }	\
   1302 	void eval_##FUNC_NAME##_bvec4	(ShaderEvalContext& c) { c.color		= FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f))).asFloat(); }
   1303 
   1304 DECLARE_FLOAT_COMPARE_FUNCS(allEqual)
   1305 DECLARE_FLOAT_COMPARE_FUNCS(anyNotEqual)
   1306 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThan)
   1307 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThanEqual)
   1308 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThan)
   1309 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThanEqual)
   1310 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(equal)
   1311 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(notEqual)
   1312 
   1313 DECLARE_INT_COMPARE_FUNCS(allEqual)
   1314 DECLARE_INT_COMPARE_FUNCS(anyNotEqual)
   1315 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThan)
   1316 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThanEqual)
   1317 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThan)
   1318 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThanEqual)
   1319 DECLARE_INT_CWISE_COMPARE_FUNCS(equal)
   1320 DECLARE_INT_CWISE_COMPARE_FUNCS(notEqual)
   1321 
   1322 DECLARE_UINT_COMPARE_FUNCS(allEqual)
   1323 DECLARE_UINT_COMPARE_FUNCS(anyNotEqual)
   1324 DECLARE_UINT_CWISE_COMPARE_FUNCS(lessThan)
   1325 DECLARE_UINT_CWISE_COMPARE_FUNCS(lessThanEqual)
   1326 DECLARE_UINT_CWISE_COMPARE_FUNCS(greaterThan)
   1327 DECLARE_UINT_CWISE_COMPARE_FUNCS(greaterThanEqual)
   1328 DECLARE_UINT_CWISE_COMPARE_FUNCS(equal)
   1329 DECLARE_UINT_CWISE_COMPARE_FUNCS(notEqual)
   1330 
   1331 DECLARE_BOOL_COMPARE_FUNCS(allEqual)
   1332 DECLARE_BOOL_COMPARE_FUNCS(anyNotEqual)
   1333 DECLARE_BOOL_CWISE_COMPARE_FUNCS(equal)
   1334 DECLARE_BOOL_CWISE_COMPARE_FUNCS(notEqual)
   1335 
   1336 // Boolean functions.
   1337 
   1338 #define DECLARE_UNARY_SCALAR_BVEC_FUNCS(GLSL_NAME, FUNC_NAME)																							\
   1339 	void eval_##GLSL_NAME##_bvec2	(ShaderEvalContext& c) { c.color.x()	= float(FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)))); }		\
   1340 	void eval_##GLSL_NAME##_bvec3	(ShaderEvalContext& c) { c.color.x()	= float(FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)))); }	\
   1341 	void eval_##GLSL_NAME##_bvec4	(ShaderEvalContext& c) { c.color.x()	= float(FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)))); }
   1342 
   1343 #define DECLARE_UNARY_BVEC_BVEC_FUNCS(GLSL_NAME, FUNC_NAME)																								\
   1344 	void eval_##GLSL_NAME##_bvec2	(ShaderEvalContext& c) { c.color.yz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); }	\
   1345 	void eval_##GLSL_NAME##_bvec3	(ShaderEvalContext& c) { c.color.xyz()	= FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); }	\
   1346 	void eval_##GLSL_NAME##_bvec4	(ShaderEvalContext& c) { c.color.xyzw()	= FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f))).asFloat(); }
   1347 
   1348 DECLARE_UNARY_SCALAR_BVEC_FUNCS(any, boolAny);
   1349 DECLARE_UNARY_SCALAR_BVEC_FUNCS(all, boolAll);
   1350 
   1351 void ShaderOperatorTests::init (void)
   1352 {
   1353 	#define BOOL_FUNCS(FUNC_NAME)			eval_##FUNC_NAME##_bool, DE_NULL, DE_NULL, DE_NULL
   1354 
   1355 	#define FLOAT_VEC_FUNCS(FUNC_NAME)		DE_NULL, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4
   1356 	#define INT_VEC_FUNCS(FUNC_NAME)		DE_NULL, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4
   1357 	#define UINT_VEC_FUNCS(FUNC_NAME)		DE_NULL, eval_##FUNC_NAME##_uvec2, eval_##FUNC_NAME##_uvec3, eval_##FUNC_NAME##_uvec4
   1358 	#define BOOL_VEC_FUNCS(FUNC_NAME)		DE_NULL, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4
   1359 
   1360 	#define FLOAT_GENTYPE_FUNCS(FUNC_NAME)	eval_##FUNC_NAME##_float, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4
   1361 	#define INT_GENTYPE_FUNCS(FUNC_NAME)	eval_##FUNC_NAME##_int, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4
   1362 	#define UINT_GENTYPE_FUNCS(FUNC_NAME)	eval_##FUNC_NAME##_uint, eval_##FUNC_NAME##_uvec2, eval_##FUNC_NAME##_uvec3, eval_##FUNC_NAME##_uvec4
   1363 	#define BOOL_GENTYPE_FUNCS(FUNC_NAME)	eval_##FUNC_NAME##_bool, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4
   1364 
   1365 	// Shorthands.
   1366 	Value					notUsed		= Value(VALUE_NONE, 0.0f, 0.0f);
   1367 	FloatScalar::Symbol		lUMax		= FloatScalar::SYMBOL_LOWP_UINT_MAX;
   1368 	FloatScalar::Symbol		mUMax		= FloatScalar::SYMBOL_MEDIUMP_UINT_MAX;
   1369 	FloatScalar::Symbol		lUMaxR		= FloatScalar::SYMBOL_LOWP_UINT_MAX_RECIPROCAL;
   1370 	FloatScalar::Symbol		mUMaxR		= FloatScalar::SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL;
   1371 
   1372 	std::vector<BuiltinFuncGroup> funcInfoGroups;
   1373 
   1374 	// Unary operators.
   1375 	funcInfoGroups.push_back(
   1376 		BuiltinFuncGroup("unary_operator", "Unary operator tests")
   1377 		<< BuiltinOperInfo						("plus",			"+",	GT,		Value(GT,  -1.0f, 1.0f),	notUsed,	notUsed,	0.5f,	0.5f,	PRECMASK_ALL,		FLOAT_GENTYPE_FUNCS(nop))
   1378 		<< BuiltinOperInfo						("plus",			"+",	IGT,	Value(IGT, -5.0f, 5.0f),	notUsed,	notUsed,	0.1f,	0.5f,	PRECMASK_ALL,		INT_GENTYPE_FUNCS(nop))
   1379 		<< BuiltinOperInfo						("plus",			"+",	UGT,	Value(UGT,  0.0f, 2e2f),	notUsed,	notUsed,	5e-3f,	0.0f,	PRECMASK_ALL,		UINT_GENTYPE_FUNCS(nop))
   1380 		<< BuiltinOperInfo						("minus",			"-",	GT,		Value(GT,  -1.0f, 1.0f),	notUsed,	notUsed,	0.5f,	0.5f,	PRECMASK_ALL,		FLOAT_GENTYPE_FUNCS(negate))
   1381 		<< BuiltinOperInfo						("minus",			"-",	IGT,	Value(IGT, -5.0f, 5.0f),	notUsed,	notUsed,	0.1f,	0.5f,	PRECMASK_ALL,		INT_GENTYPE_FUNCS(negate))
   1382 		<< BuiltinOperInfoSeparateRefScaleBias	("minus",			"-",	UGT,	Value(UGT,  0.0f, lUMax),	notUsed,	notUsed,	lUMaxR,	0.0f,	PRECMASK_LOWP,		UINT_GENTYPE_FUNCS(negate), lUMaxR, FloatScalar::SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX)
   1383 		<< BuiltinOperInfoSeparateRefScaleBias	("minus",			"-",	UGT,	Value(UGT,  0.0f, mUMax),	notUsed,	notUsed,	mUMaxR,	0.0f,	PRECMASK_MEDIUMP,	UINT_GENTYPE_FUNCS(negate), mUMaxR, FloatScalar::SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX)
   1384 		<< BuiltinOperInfo						("minus",			"-",	UGT,	Value(UGT,  0.0f, 4e9f),	notUsed,	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,		UINT_GENTYPE_FUNCS(negate))
   1385 		<< BuiltinOperInfo						("not",				"!",	B,		Value(B,   -1.0f, 1.0f),	notUsed,	notUsed,	1.0f,	0.0f,	PRECMASK_NA,		eval_boolNot_bool, DE_NULL, DE_NULL, DE_NULL)
   1386 		<< BuiltinOperInfo						("bitwise_not",		"~",	IGT,	Value(IGT, -1e5f, 1e5f),	notUsed,	notUsed,	5e-5f,	0.5f,	PRECMASK_HIGHP,		INT_GENTYPE_FUNCS(bitwiseNot))
   1387 		<< BuiltinOperInfo						("bitwise_not",		"~",	UGT,	Value(UGT,  0.0f, 2e9f),	notUsed,	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,		UINT_GENTYPE_FUNCS(bitwiseNot))
   1388 
   1389 		// Pre/post incr/decr side effect cases.
   1390 		<< BuiltinSideEffOperInfo		("pre_increment_effect",	"++",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 0.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(addOne))
   1391 		<< BuiltinSideEffOperInfo		("pre_increment_effect",	"++",	IGT,	Value(IGT,	-6.0f, 4.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(addOne))
   1392 		<< BuiltinSideEffOperInfo		("pre_increment_effect",	"++",	UGT,	Value(UGT,	 0.0f, 9.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(addOne))
   1393 		<< BuiltinSideEffOperInfo		("pre_decrement_effect",	"--",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 1.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(subOne))
   1394 		<< BuiltinSideEffOperInfo		("pre_decrement_effect",	"--",	IGT,	Value(IGT,	-4.0f, 6.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(subOne))
   1395 		<< BuiltinSideEffOperInfo		("pre_decrement_effect",	"--",	UGT,	Value(UGT,	 1.0f, 10.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(subOne))
   1396 		<< BuiltinPostSideEffOperInfo	("post_increment_effect",	"++",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 0.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(addOne))
   1397 		<< BuiltinPostSideEffOperInfo	("post_increment_effect",	"++",	IGT,	Value(IGT,	-6.0f, 4.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(addOne))
   1398 		<< BuiltinPostSideEffOperInfo	("post_increment_effect",	"++",	UGT,	Value(UGT,	 0.0f, 9.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(addOne))
   1399 		<< BuiltinPostSideEffOperInfo	("post_decrement_effect",	"--",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 1.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(subOne))
   1400 		<< BuiltinPostSideEffOperInfo	("post_decrement_effect",	"--",	IGT,	Value(IGT,	-4.0f, 6.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(subOne))
   1401 		<< BuiltinPostSideEffOperInfo	("post_decrement_effect",	"--",	UGT,	Value(UGT,	 1.0f, 10.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(subOne))
   1402 
   1403 		// Pre/post incr/decr result cases.
   1404 		<< BuiltinOperInfo				("pre_increment_result",	"++",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 0.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(addOne))
   1405 		<< BuiltinOperInfo				("pre_increment_result",	"++",	IGT,	Value(IGT,	-6.0f, 4.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(addOne))
   1406 		<< BuiltinOperInfo				("pre_increment_result",	"++",	UGT,	Value(UGT,	 0.0f, 9.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(addOne))
   1407 		<< BuiltinOperInfo				("pre_decrement_result",	"--",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 1.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(subOne))
   1408 		<< BuiltinOperInfo				("pre_decrement_result",	"--",	IGT,	Value(IGT,	-4.0f, 6.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(subOne))
   1409 		<< BuiltinOperInfo				("pre_decrement_result",	"--",	UGT,	Value(UGT,	 1.0f, 10.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(subOne))
   1410 		<< BuiltinPostOperInfo			("post_increment_result",	"++",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 0.5f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(nop))
   1411 		<< BuiltinPostOperInfo			("post_increment_result",	"++",	IGT,	Value(IGT,	-5.0f, 5.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(nop))
   1412 		<< BuiltinPostOperInfo			("post_increment_result",	"++",	UGT,	Value(UGT,	 0.0f, 9.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(nop))
   1413 		<< BuiltinPostOperInfo			("post_decrement_result",	"--",	GT,		Value(GT,	-1.0f, 1.0f),	notUsed,	notUsed,	0.5f, 0.5f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(nop))
   1414 		<< BuiltinPostOperInfo			("post_decrement_result",	"--",	IGT,	Value(IGT,	-5.0f, 5.0f),	notUsed,	notUsed,	0.1f, 0.5f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(nop))
   1415 		<< BuiltinPostOperInfo			("post_decrement_result",	"--",	UGT,	Value(UGT,	 1.0f, 10.0f),	notUsed,	notUsed,	0.1f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(nop))
   1416 	);
   1417 
   1418 	BuiltinFuncGroup binaryOpGroup("binary_operator", "Binary operator tests");
   1419 
   1420 	// Normal binary operations and their corresponding assignment operations have lots in common; generate both in the following loop.
   1421 
   1422 	for (int binaryOperatorType = 0; binaryOperatorType <= 2; binaryOperatorType++) // 0: normal op test, 1: assignment op side-effect test, 2: assignment op result test
   1423 	{
   1424 		bool		isNormalOp		= binaryOperatorType == 0;
   1425 		bool		isAssignEff		= binaryOperatorType == 1;
   1426 		bool		isAssignRes		= binaryOperatorType == 2;
   1427 
   1428 		DE_ASSERT(isNormalOp || isAssignEff || isAssignRes);
   1429 		DE_UNREF(isAssignRes);
   1430 
   1431 		const char*	addName			= isNormalOp ? "add"			: isAssignEff ? "add_assign_effect"			: "add_assign_result";
   1432 		const char*	subName			= isNormalOp ? "sub"			: isAssignEff ? "sub_assign_effect"			: "sub_assign_result";
   1433 		const char*	mulName			= isNormalOp ? "mul"			: isAssignEff ? "mul_assign_effect"			: "mul_assign_result";
   1434 		const char*	divName			= isNormalOp ? "div"			: isAssignEff ? "div_assign_effect"			: "div_assign_result";
   1435 		const char* modName			= isNormalOp ? "mod"			: isAssignEff ? "mod_assign_effect"			: "mod_assign_result";
   1436 		const char* andName			= isNormalOp ? "bitwise_and"	: isAssignEff ? "bitwise_and_assign_effect"	: "bitwise_and_assign_result";
   1437 		const char* orName			= isNormalOp ? "bitwise_or"		: isAssignEff ? "bitwise_or_assign_effect"	: "bitwise_or_assign_result";
   1438 		const char* xorName			= isNormalOp ? "bitwise_xor"	: isAssignEff ? "bitwise_xor_assign_effect"	: "bitwise_xor_assign_result";
   1439 		const char* leftShiftName	= isNormalOp ? "left_shift"		: isAssignEff ? "left_shift_assign_effect"	: "left_shift_assign_result";
   1440 		const char* rightShiftName	= isNormalOp ? "right_shift"	: isAssignEff ? "right_shift_assign_effect"	: "right_shift_assign_result";
   1441 		const char*	addOp			= isNormalOp ? "+" : "+=";
   1442 		const char*	subOp			= isNormalOp ? "-" : "-=";
   1443 		const char*	mulOp			= isNormalOp ? "*" : "*=";
   1444 		const char*	divOp			= isNormalOp ? "/" : "/=";
   1445 		const char*	modOp			= isNormalOp ? "%" : "%=";
   1446 		const char*	andOp			= isNormalOp ? "&" : "&=";
   1447 		const char*	orOp			= isNormalOp ? "|" : "|=";
   1448 		const char*	xorOp			= isNormalOp ? "^" : "^=";
   1449 		const char*	leftShiftOp		= isNormalOp ? "<<" : "<<=";
   1450 		const char*	rightShiftOp	= isNormalOp ? ">>" : ">>=";
   1451 
   1452 		// Pointer to appropriate OperInfo function.
   1453 		BuiltinFuncInfo (*operInfoFunc)(const char*, const char*, ValueType, Value, Value, Value, const FloatScalar&, const FloatScalar&, deUint32, ShaderEvalFunc, ShaderEvalFunc, ShaderEvalFunc, ShaderEvalFunc) =
   1454 			isAssignEff ? BuiltinSideEffOperInfo : BuiltinOperInfo;
   1455 
   1456 		DE_ASSERT(operInfoFunc != DE_NULL);
   1457 
   1458 		// The following cases will be added for each operator, precision and fundamental type (float, int, uint) combination, where applicable:
   1459 		// gentype <op> gentype
   1460 		// vector <op> scalar
   1461 		// For normal (non-assigning) operators only:
   1462 		//   scalar <op> vector
   1463 
   1464 		// The add operator.
   1465 
   1466 		binaryOpGroup
   1467 			<< operInfoFunc(addName,	addOp,	GT,		Value(GT,  -1.0f, 1.0f),	Value(GT,  -1.0f, 1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_GENTYPE_FUNCS(add))
   1468 			<< operInfoFunc(addName,	addOp,	IGT,	Value(IGT, -4.0f, 6.0f),	Value(IGT, -6.0f, 5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(add))
   1469 			<< operInfoFunc(addName,	addOp,	IGT,	Value(IGT, -2e9f, 2e9f),	Value(IGT, -2e9f, 2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(add))
   1470 			<< operInfoFunc(addName,	addOp,	UGT,	Value(UGT,  0.0f, 1e2f),	Value(UGT,  0.0f, 1e2f),	notUsed,	5e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(add))
   1471 			<< operInfoFunc(addName,	addOp,	UGT,	Value(UGT,  0.0f, 4e9f),	Value(UGT,  0.0f, 4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(add))
   1472 			<< operInfoFunc(addName,	addOp,	FV,		Value(FV,  -1.0f, 1.0f),	Value(F,   -1.0f, 1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(addVecScalar))
   1473 			<< operInfoFunc(addName,	addOp,	IV,		Value(IV,  -4.0f, 6.0f),	Value(I,   -6.0f, 5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(addVecScalar))
   1474 			<< operInfoFunc(addName,	addOp,	IV,		Value(IV,  -2e9f, 2e9f),	Value(I,   -2e9f, 2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(addVecScalar))
   1475 			<< operInfoFunc(addName,	addOp,	UV,		Value(UV,   0.0f, 1e2f),	Value(U,    0.0f, 1e2f),	notUsed,	5e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(addVecScalar))
   1476 			<< operInfoFunc(addName,	addOp,	UV,		Value(UV,   0.0f, 4e9f),	Value(U,    0.0f, 4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(addVecScalar));
   1477 
   1478 		if (isNormalOp)
   1479 			binaryOpGroup
   1480 				<< operInfoFunc(addName,	addOp,	FV,		Value(F,   -1.0f, 1.0f),	Value(FV,  -1.0f, 1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(addScalarVec))
   1481 				<< operInfoFunc(addName,	addOp,	IV,		Value(I,   -4.0f, 6.0f),	Value(IV,  -6.0f, 5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(addScalarVec))
   1482 				<< operInfoFunc(addName,	addOp,	IV,		Value(I,   -2e9f, 2e9f),	Value(IV,  -2e9f, 2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(addScalarVec))
   1483 				<< operInfoFunc(addName,	addOp,	UV,		Value(U,    0.0f, 1e2f),	Value(UV,   0.0f, 1e2f),	notUsed,	5e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(addScalarVec))
   1484 				<< operInfoFunc(addName,	addOp,	UV,		Value(U,    0.0f, 4e9f),	Value(UV,   0.0f, 4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(addScalarVec));
   1485 
   1486 		// The subtract operator.
   1487 
   1488 		binaryOpGroup
   1489 			<< operInfoFunc(subName,	subOp,	GT,		Value(GT,  -1.0f, 1.0f),	Value(GT,  -1.0f, 1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_GENTYPE_FUNCS(sub))
   1490 			<< operInfoFunc(subName,	subOp,	IGT,	Value(IGT, -4.0f, 6.0f),	Value(IGT, -6.0f, 5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(sub))
   1491 			<< operInfoFunc(subName,	subOp,	IGT,	Value(IGT, -2e9f, 2e9f),	Value(IGT, -2e9f, 2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(sub))
   1492 			<< operInfoFunc(subName,	subOp,	UGT,	Value(UGT,  1e2f, 2e2f),	Value(UGT,  0.0f, 1e2f),	notUsed,	5e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(sub))
   1493 			<< operInfoFunc(subName,	subOp,	UGT,	Value(UGT,  .5e9f, 3.7e9f),	Value(UGT,  0.0f, 3.9e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(sub))
   1494 			<< operInfoFunc(subName,	subOp,	FV,		Value(FV,  -1.0f, 1.0f),	Value(F,   -1.0f, 1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(subVecScalar))
   1495 			<< operInfoFunc(subName,	subOp,	IV,		Value(IV,  -4.0f, 6.0f),	Value(I,   -6.0f, 5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(subVecScalar))
   1496 			<< operInfoFunc(subName,	subOp,	IV,		Value(IV,  -2e9f, 2e9f),	Value(I,   -2e9f, 2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(subVecScalar))
   1497 			<< operInfoFunc(subName,	subOp,	UV,		Value(UV,   1e2f, 2e2f),	Value(U,    0.0f, 1e2f),	notUsed,	5e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(subVecScalar))
   1498 			<< operInfoFunc(subName,	subOp,	UV,		Value(UV,   0.0f, 4e9f),	Value(U,    0.0f, 4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(subVecScalar));
   1499 
   1500 		if (isNormalOp)
   1501 			binaryOpGroup
   1502 				<< operInfoFunc(subName,	subOp,	FV,		Value(F,   -1.0f, 1.0f),	Value(FV,  -1.0f, 1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(subScalarVec))
   1503 				<< operInfoFunc(subName,	subOp,	IV,		Value(I,   -4.0f, 6.0f),	Value(IV,  -6.0f, 5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(subScalarVec))
   1504 				<< operInfoFunc(subName,	subOp,	IV,		Value(I,   -2e9f, 2e9f),	Value(IV,  -2e9f, 2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(subScalarVec))
   1505 				<< operInfoFunc(subName,	subOp,	UV,		Value(U,    1e2f, 2e2f),	Value(UV,    0.0f, 1e2f),	notUsed,	5e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(subScalarVec))
   1506 				<< operInfoFunc(subName,	subOp,	UV,		Value(U,    0.0f, 4e9f),	Value(UV,    0.0f, 4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(subScalarVec));
   1507 
   1508 		// The multiply operator.
   1509 
   1510 		binaryOpGroup
   1511 			<< operInfoFunc(mulName,	mulOp,	GT,		Value(GT,  -1.0f, 1.0f),	Value(GT,  -1.0f, 1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_GENTYPE_FUNCS(mul))
   1512 			<< operInfoFunc(mulName,	mulOp,	IGT,	Value(IGT, -4.0f, 6.0f),	Value(IGT, -6.0f, 5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(mul))
   1513 			<< operInfoFunc(mulName,	mulOp,	IGT,	Value(IGT, -3e5f, 3e5f),	Value(IGT, -3e4f, 3e4f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(mul))
   1514 			<< operInfoFunc(mulName,	mulOp,	UGT,	Value(UGT,  0.0f, 16.0f),	Value(UGT,  0.0f, 16.0f),	notUsed,	4e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(mul))
   1515 			<< operInfoFunc(mulName,	mulOp,	UGT,	Value(UGT,  0.0f, 6e5f),	Value(UGT,  0.0f, 6e4f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(mul))
   1516 			<< operInfoFunc(mulName,	mulOp,	FV,		Value(FV,  -1.0f, 1.0f),	Value(F,   -1.0f,  1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(mulVecScalar))
   1517 			<< operInfoFunc(mulName,	mulOp,	IV,		Value(IV,  -4.0f, 6.0f),	Value(I,   -6.0f,  5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(mulVecScalar))
   1518 			<< operInfoFunc(mulName,	mulOp,	IV,		Value(IV,  -3e5f, 3e5f),	Value(I,   -3e4f,  3e4f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(mulVecScalar))
   1519 			<< operInfoFunc(mulName,	mulOp,	UV,		Value(UV,   0.0f, 16.0f),	Value(U,    0.0f, 16.0f),	notUsed,	4e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(mulVecScalar))
   1520 			<< operInfoFunc(mulName,	mulOp,	UV,		Value(UV,   0.0f, 6e5f),	Value(U,    0.0f, 6e4f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(mulVecScalar));
   1521 
   1522 		if (isNormalOp)
   1523 			binaryOpGroup
   1524 				<< operInfoFunc(mulName,	mulOp,	FV,		Value(F,   -1.0f, 1.0f),	Value(FV,  -1.0f,  1.0f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(mulScalarVec))
   1525 				<< operInfoFunc(mulName,	mulOp,	IV,		Value(I,   -4.0f, 6.0f),	Value(IV,  -6.0f,  5.0f),	notUsed,	0.1f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(mulScalarVec))
   1526 				<< operInfoFunc(mulName,	mulOp,	IV,		Value(I,   -3e5f, 3e5f),	Value(IV,  -3e4f,  3e4f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(mulScalarVec))
   1527 				<< operInfoFunc(mulName,	mulOp,	UV,		Value(U,    0.0f, 16.0f),	Value(UV,   0.0f, 16.0f),	notUsed,	4e-3f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(mulScalarVec))
   1528 				<< operInfoFunc(mulName,	mulOp,	UV,		Value(U,    0.0f, 6e5f),	Value(UV,   0.0f, 6e4f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(mulScalarVec));
   1529 
   1530 		// The divide operator.
   1531 
   1532 		binaryOpGroup
   1533 			<< operInfoFunc(divName,	divOp,	GT,		Value(GT,  -1.0f,    1.0f),		Value(GT,  -2.0f, -0.5f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_GENTYPE_FUNCS(div))
   1534 			<< operInfoFunc(divName,	divOp,	IGT,	Value(IGT, 24.0f,    24.0f),	Value(IGT, -4.0f, -1.0f),	notUsed,	0.04f,	1.0f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(div))
   1535 			<< operInfoFunc(divName,	divOp,	IGT,	Value(IGT, 40320.0f, 40320.0f),	Value(IGT, -8.0f, -1.0f),	notUsed,	1e-5f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(div))
   1536 			<< operInfoFunc(divName,	divOp,	UGT,	Value(UGT,  0.0f,    24.0f),	Value(UGT,  1.0f,  4.0f),	notUsed,	0.04f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(div))
   1537 			<< operInfoFunc(divName,	divOp,	UGT,	Value(UGT,  0.0f,    40320.0f),	Value(UGT,  1.0f,  8.0f),	notUsed,	1e-5f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(div))
   1538 			<< operInfoFunc(divName,	divOp,	FV,		Value(FV,  -1.0f,    1.0f),		Value(F,   -2.0f, -0.5f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(divVecScalar))
   1539 			<< operInfoFunc(divName,	divOp,	IV,		Value(IV,  24.0f,    24.0f),	Value(I,   -4.0f, -1.0f),	notUsed,	0.04f,	1.0f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(divVecScalar))
   1540 			<< operInfoFunc(divName,	divOp,	IV,		Value(IV,  40320.0f, 40320.0f),	Value(I,   -8.0f, -1.0f),	notUsed,	1e-5f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(divVecScalar))
   1541 			<< operInfoFunc(divName,	divOp,	UV,		Value(UV,   0.0f,    24.0f),	Value(U,    1.0f,  4.0f),	notUsed,	0.04f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(divVecScalar))
   1542 			<< operInfoFunc(divName,	divOp,	UV,		Value(UV,   0.0f,    40320.0f),	Value(U,    1.0f,  8.0f),	notUsed,	1e-5f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(divVecScalar));
   1543 
   1544 		if (isNormalOp)
   1545 			binaryOpGroup
   1546 				<< operInfoFunc(divName,	divOp,	FV,		Value(F,   -1.0f,    1.0f),		Value(FV,  -2.0f, -0.5f),	notUsed,	1.0f,	0.0f,	PRECMASK_ALL,			FLOAT_VEC_FUNCS(divScalarVec))
   1547 				<< operInfoFunc(divName,	divOp,	IV,		Value(I,   24.0f,    24.0f),	Value(IV,  -4.0f, -1.0f),	notUsed,	0.04f,	1.0f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(divScalarVec))
   1548 				<< operInfoFunc(divName,	divOp,	IV,		Value(I,   40320.0f, 40320.0f),	Value(IV,  -8.0f, -1.0f),	notUsed,	1e-5f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(divScalarVec))
   1549 				<< operInfoFunc(divName,	divOp,	UV,		Value(U,    0.0f,    24.0f),	Value(UV,   1.0f,  4.0f),	notUsed,	0.04f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(divScalarVec))
   1550 				<< operInfoFunc(divName,	divOp,	UV,		Value(U,    0.0f,    40320.0f),	Value(UV,   1.0f,  8.0f),	notUsed,	1e-5f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(divScalarVec));
   1551 
   1552 		// The modulus operator.
   1553 
   1554 		binaryOpGroup
   1555 			<< operInfoFunc(modName,	modOp,	IGT,	Value(IGT,  0.0f, 6.0f),	Value(IGT,   1.1f,  6.1f),	notUsed,	0.25f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(mod))
   1556 			<< operInfoFunc(modName,	modOp,	IGT,	Value(IGT,  0.0f, 14.0f),	Value(IGT,   1.1f, 11.1f),	notUsed,	0.1f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(mod))
   1557 			<< operInfoFunc(modName,	modOp,	UGT,	Value(UGT,  0.0f, 6.0f),	Value(UGT,   1.1f,  6.1f),	notUsed,	0.25f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(mod))
   1558 			<< operInfoFunc(modName,	modOp,	UGT,	Value(UGT,  0.0f, 24.0f),	Value(UGT,   1.1f, 11.1f),	notUsed,	0.1f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(mod))
   1559 			<< operInfoFunc(modName,	modOp,	IV,		Value(IV,   0.0f, 6.0f),	Value(I,     1.1f,  6.1f),	notUsed,	0.25f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(modVecScalar))
   1560 			<< operInfoFunc(modName,	modOp,	IV,		Value(IV,   0.0f, 6.0f),	Value(I,     1.1f, 11.1f),	notUsed,	0.1f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(modVecScalar))
   1561 			<< operInfoFunc(modName,	modOp,	UV,		Value(UV,   0.0f, 6.0f),	Value(U,     1.1f,  6.1f),	notUsed,	0.25f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(modVecScalar))
   1562 			<< operInfoFunc(modName,	modOp,	UV,		Value(UV,   0.0f, 24.0f),	Value(U,     1.1f, 11.1f),	notUsed,	0.1f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(modVecScalar));
   1563 
   1564 		if (isNormalOp)
   1565 			binaryOpGroup
   1566 				<< operInfoFunc(modName,	modOp,	IV,		Value(I,   0.0f, 6.0f),		Value(IV,     1.1f,  6.1f),	notUsed,	0.25f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(modScalarVec))
   1567 				<< operInfoFunc(modName,	modOp,	IV,		Value(I,   0.0f, 6.0f),		Value(IV,     1.1f, 11.1f),	notUsed,	0.1f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(modScalarVec))
   1568 				<< operInfoFunc(modName,	modOp,	UV,		Value(U,   0.0f, 6.0f),		Value(UV,     1.1f,  6.1f),	notUsed,	0.25f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(modScalarVec))
   1569 				<< operInfoFunc(modName,	modOp,	UV,		Value(U,   0.0f, 24.0f),	Value(UV,     1.1f, 11.1f),	notUsed,	0.1f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(modScalarVec));
   1570 
   1571 		// The bitwise and operator.
   1572 
   1573 		binaryOpGroup
   1574 			<< operInfoFunc(andName,	andOp,	IGT,	Value(IGT, -16.0f, 16.0f),	Value(IGT, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(bitwiseAnd))
   1575 			<< operInfoFunc(andName,	andOp,	IGT,	Value(IGT,  -2e9f,  2e9f),	Value(IGT,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(bitwiseAnd))
   1576 			<< operInfoFunc(andName,	andOp,	UGT,	Value(UGT,   0.0f, 32.0f),	Value(UGT,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(bitwiseAnd))
   1577 			<< operInfoFunc(andName,	andOp,	UGT,	Value(UGT,   0.0f,  4e9f),	Value(UGT,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(bitwiseAnd))
   1578 			<< operInfoFunc(andName,	andOp,	IV,		Value(IV, -16.0f, 16.0f),	Value(I, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(bitwiseAndVecScalar))
   1579 			<< operInfoFunc(andName,	andOp,	IV,		Value(IV,  -2e9f,  2e9f),	Value(I,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(bitwiseAndVecScalar))
   1580 			<< operInfoFunc(andName,	andOp,	UV,		Value(UV,   0.0f, 32.0f),	Value(U,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(bitwiseAndVecScalar))
   1581 			<< operInfoFunc(andName,	andOp,	UV,		Value(UV,   0.0f,  4e9f),	Value(U,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(bitwiseAndVecScalar));
   1582 
   1583 		if (isNormalOp)
   1584 			binaryOpGroup
   1585 				<< operInfoFunc(andName,	andOp,	IV,		Value(I, -16.0f, 16.0f),	Value(IV, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(bitwiseAndScalarVec))
   1586 				<< operInfoFunc(andName,	andOp,	IV,		Value(I,  -2e9f,  2e9f),	Value(IV,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(bitwiseAndScalarVec))
   1587 				<< operInfoFunc(andName,	andOp,	UV,		Value(U,   0.0f, 32.0f),	Value(UV,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(bitwiseAndScalarVec))
   1588 				<< operInfoFunc(andName,	andOp,	UV,		Value(U,   0.0f,  4e9f),	Value(UV,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(bitwiseAndScalarVec));
   1589 
   1590 		// The bitwise or operator.
   1591 
   1592 		binaryOpGroup
   1593 			<< operInfoFunc(orName,	orOp,	IGT,	Value(IGT, -16.0f, 16.0f),	Value(IGT, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(bitwiseOr))
   1594 			<< operInfoFunc(orName,	orOp,	IGT,	Value(IGT,  -2e9f,  2e9f),	Value(IGT,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(bitwiseOr))
   1595 			<< operInfoFunc(orName,	orOp,	UGT,	Value(UGT,   0.0f, 32.0f),	Value(UGT,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(bitwiseOr))
   1596 			<< operInfoFunc(orName,	orOp,	UGT,	Value(UGT,   0.0f,  4e9f),	Value(UGT,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(bitwiseOr))
   1597 			<< operInfoFunc(orName,	orOp,	IV,		Value(IV, -16.0f, 16.0f),	Value(I, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(bitwiseOrVecScalar))
   1598 			<< operInfoFunc(orName,	orOp,	IV,		Value(IV,  -2e9f,  2e9f),	Value(I,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(bitwiseOrVecScalar))
   1599 			<< operInfoFunc(orName,	orOp,	UV,		Value(UV,   0.0f, 32.0f),	Value(U,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(bitwiseOrVecScalar))
   1600 			<< operInfoFunc(orName,	orOp,	UV,		Value(UV,   0.0f,  4e9f),	Value(U,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(bitwiseOrVecScalar));
   1601 
   1602 		if (isNormalOp)
   1603 			binaryOpGroup
   1604 				<< operInfoFunc(orName,	orOp,	IV,		Value(I, -16.0f, 16.0f),	Value(IV, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(bitwiseOrScalarVec))
   1605 				<< operInfoFunc(orName,	orOp,	IV,		Value(I,  -2e9f,  2e9f),	Value(IV,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(bitwiseOrScalarVec))
   1606 				<< operInfoFunc(orName,	orOp,	UV,		Value(U,   0.0f, 32.0f),	Value(UV,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(bitwiseOrScalarVec))
   1607 				<< operInfoFunc(orName,	orOp,	UV,		Value(U,   0.0f,  4e9f),	Value(UV,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(bitwiseOrScalarVec));
   1608 
   1609 		// The bitwise xor operator.
   1610 
   1611 		binaryOpGroup
   1612 			<< operInfoFunc(xorName,	xorOp,	IGT,	Value(IGT, -16.0f, 16.0f),	Value(IGT, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(bitwiseXor))
   1613 			<< operInfoFunc(xorName,	xorOp,	IGT,	Value(IGT,  -2e9f,  2e9f),	Value(IGT,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(bitwiseXor))
   1614 			<< operInfoFunc(xorName,	xorOp,	UGT,	Value(UGT,   0.0f, 32.0f),	Value(UGT,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(bitwiseXor))
   1615 			<< operInfoFunc(xorName,	xorOp,	UGT,	Value(UGT,   0.0f,  4e9f),	Value(UGT,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(bitwiseXor))
   1616 			<< operInfoFunc(xorName,	xorOp,	IV,		Value(IV, -16.0f, 16.0f),	Value(I, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(bitwiseXorVecScalar))
   1617 			<< operInfoFunc(xorName,	xorOp,	IV,		Value(IV,  -2e9f,  2e9f),	Value(I,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(bitwiseXorVecScalar))
   1618 			<< operInfoFunc(xorName,	xorOp,	UV,		Value(UV,   0.0f, 32.0f),	Value(U,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(bitwiseXorVecScalar))
   1619 			<< operInfoFunc(xorName,	xorOp,	UV,		Value(UV,   0.0f,  4e9f),	Value(U,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(bitwiseXorVecScalar));
   1620 
   1621 		if (isNormalOp)
   1622 			binaryOpGroup
   1623 				<< operInfoFunc(xorName,	xorOp,	IV,		Value(I, -16.0f, 16.0f),	Value(IV, -16.0f, 16.0f),	notUsed,	 0.03f,	0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(bitwiseXorScalarVec))
   1624 				<< operInfoFunc(xorName,	xorOp,	IV,		Value(I,  -2e9f,  2e9f),	Value(IV,  -2e9f,  2e9f),	notUsed,	4e-10f,	0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(bitwiseXorScalarVec))
   1625 				<< operInfoFunc(xorName,	xorOp,	UV,		Value(U,   0.0f, 32.0f),	Value(UV,   0.0f, 32.0f),	notUsed,	 0.03f,	0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(bitwiseXorScalarVec))
   1626 				<< operInfoFunc(xorName,	xorOp,	UV,		Value(U,   0.0f,  4e9f),	Value(UV,   0.0f,  4e9f),	notUsed,	2e-10f,	0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(bitwiseXorScalarVec));
   1627 
   1628 		// The left shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
   1629 
   1630 		for (int isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++)
   1631 		{
   1632 			ValueType gType = isSignedAmount == 0 ? UGT	: IGT;
   1633 			ValueType sType = isSignedAmount == 0 ? U	: I;
   1634 			binaryOpGroup
   1635 				<< operInfoFunc(leftShiftName,	leftShiftOp,	IGT,	Value(IGT, -7.0f, 7.0f),	Value(gType, 0.0f, 4.0f),	notUsed,	4e-3f,  0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(leftShift))
   1636 				<< operInfoFunc(leftShiftName,	leftShiftOp,	IGT,	Value(IGT, -7.0f, 7.0f),	Value(gType, 0.0f, 27.0f),	notUsed,	5e-10f, 0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(leftShift))
   1637 				<< operInfoFunc(leftShiftName,	leftShiftOp,	UGT,	Value(UGT,  0.0f, 7.0f),	Value(gType, 0.0f, 5.0f),	notUsed,	4e-3f,  0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(leftShift))
   1638 				<< operInfoFunc(leftShiftName,	leftShiftOp,	UGT,	Value(UGT,  0.0f, 7.0f),	Value(gType, 0.0f, 28.0f),	notUsed,	5e-10f, 0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(leftShift))
   1639 				<< operInfoFunc(leftShiftName,	leftShiftOp,	IV,		Value(IV,  -7.0f, 7.0f),	Value(sType, 0.0f, 4.0f),	notUsed,	4e-3f,  0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(leftShiftVecScalar))
   1640 				<< operInfoFunc(leftShiftName,	leftShiftOp,	IV,		Value(IV,  -7.0f, 7.0f),	Value(sType, 0.0f, 27.0f),	notUsed,	5e-10f, 0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(leftShiftVecScalar))
   1641 				<< operInfoFunc(leftShiftName,	leftShiftOp,	UV,		Value(UV,   0.0f, 7.0f),	Value(sType, 0.0f, 5.0f),	notUsed,	4e-3f,  0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(leftShiftVecScalar))
   1642 				<< operInfoFunc(leftShiftName,	leftShiftOp,	UV,		Value(UV,   0.0f, 7.0f),	Value(sType, 0.0f, 28.0f),	notUsed,	5e-10f, 0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(leftShiftVecScalar));
   1643 		}
   1644 
   1645 		// The right shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
   1646 
   1647 		for (int isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++)
   1648 		{
   1649 			ValueType gType = isSignedAmount == 0 ? UGT	: IGT;
   1650 			ValueType sType = isSignedAmount == 0 ? U	: I;
   1651 			binaryOpGroup
   1652 				<< operInfoFunc(rightShiftName,	rightShiftOp,	IGT,	Value(IGT, -127.0f, 127.0f),	Value(gType, 0.0f, 8.0f),	notUsed,	4e-3f,  0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_GENTYPE_FUNCS(rightShift))
   1653 				<< operInfoFunc(rightShiftName,	rightShiftOp,	IGT,	Value(IGT, -2e9f, 2e9f),		Value(gType, 0.0f, 31.0f),	notUsed,	5e-10f, 0.5f,	PRECMASK_HIGHP,			INT_GENTYPE_FUNCS(rightShift))
   1654 				<< operInfoFunc(rightShiftName,	rightShiftOp,	UGT,	Value(UGT,  0.0f, 255.0f),		Value(gType, 0.0f, 8.0f),	notUsed,	4e-3f,  0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_GENTYPE_FUNCS(rightShift))
   1655 				<< operInfoFunc(rightShiftName,	rightShiftOp,	UGT,	Value(UGT,  0.0f, 4e9f),		Value(gType, 0.0f, 31.0f),	notUsed,	5e-10f, 0.0f,	PRECMASK_HIGHP,			UINT_GENTYPE_FUNCS(rightShift))
   1656 				<< operInfoFunc(rightShiftName,	rightShiftOp,	IV,		Value(IV,  -127.0f, 127.0f),	Value(sType, 0.0f, 8.0f),	notUsed,	4e-3f,  0.5f,	PRECMASK_LOWP_MEDIUMP,	INT_VEC_FUNCS(rightShiftVecScalar))
   1657 				<< operInfoFunc(rightShiftName,	rightShiftOp,	IV,		Value(IV,  -2e9f, 2e9f),		Value(sType, 0.0f, 31.0f),	notUsed,	5e-10f, 0.5f,	PRECMASK_HIGHP,			INT_VEC_FUNCS(rightShiftVecScalar))
   1658 				<< operInfoFunc(rightShiftName,	rightShiftOp,	UV,		Value(UV,   0.0f, 255.0f),		Value(sType, 0.0f, 8.0f),	notUsed,	4e-3f,  0.0f,	PRECMASK_LOWP_MEDIUMP,	UINT_VEC_FUNCS(rightShiftVecScalar))
   1659 				<< operInfoFunc(rightShiftName,	rightShiftOp,	UV,		Value(UV,   0.0f, 4e9f),		Value(sType, 0.0f, 31.0f),	notUsed,	5e-10f, 0.0f,	PRECMASK_HIGHP,			UINT_VEC_FUNCS(rightShiftVecScalar));
   1660 		}
   1661 	}
   1662 
   1663 	// Rest of binary operators.
   1664 
   1665 	binaryOpGroup
   1666 		// Scalar relational operators.
   1667 		<< BuiltinOperInfo("less",				"<",	B,		Value(F,   -1.0f, 1.0f),	Value(F,   -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_lessThan_float,			DE_NULL, DE_NULL, DE_NULL)
   1668 		<< BuiltinOperInfo("less",				"<",	B,		Value(I,   -5.0f, 5.0f),	Value(I,   -5.0f, 5.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_lessThan_int,				DE_NULL, DE_NULL, DE_NULL)
   1669 		<< BuiltinOperInfo("less",				"<",	B,		Value(U,    0.0f, 16.0f),	Value(U,    0.0f, 16.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_lessThan_uint,				DE_NULL, DE_NULL, DE_NULL)
   1670 		<< BuiltinOperInfo("less_or_equal",		"<=",	B,		Value(F,   -1.0f, 1.0f),	Value(F,   -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_lessThanEqual_float,		DE_NULL, DE_NULL, DE_NULL)
   1671 		<< BuiltinOperInfo("less_or_equal",		"<=",	B,		Value(I,   -5.0f, 5.0f),	Value(I,   -5.0f, 5.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_lessThanEqual_int,			DE_NULL, DE_NULL, DE_NULL)
   1672 		<< BuiltinOperInfo("less_or_equal",		"<=",	B,		Value(U,    0.0f, 16.0f),	Value(U,    0.0f, 16.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_lessThanEqual_uint,		DE_NULL, DE_NULL, DE_NULL)
   1673 		<< BuiltinOperInfo("greater",			">",	B,		Value(F,   -1.0f, 1.0f),	Value(F,   -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_greaterThan_float,			DE_NULL, DE_NULL, DE_NULL)
   1674 		<< BuiltinOperInfo("greater",			">",	B,		Value(I,   -5.0f, 5.0f),	Value(I,   -5.0f, 5.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_greaterThan_int,			DE_NULL, DE_NULL, DE_NULL)
   1675 		<< BuiltinOperInfo("greater",			">",	B,		Value(U,    0.0f, 16.0f),	Value(U,    0.0f, 16.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_greaterThan_uint,			DE_NULL, DE_NULL, DE_NULL)
   1676 		<< BuiltinOperInfo("greater_or_equal",	">=",	B,		Value(F,   -1.0f, 1.0f),	Value(F,   -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_greaterThanEqual_float,	DE_NULL, DE_NULL, DE_NULL)
   1677 		<< BuiltinOperInfo("greater_or_equal",	">=",	B,		Value(I,   -5.0f, 5.0f),	Value(I,   -5.0f, 5.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_greaterThanEqual_int,		DE_NULL, DE_NULL, DE_NULL)
   1678 		<< BuiltinOperInfo("greater_or_equal",	">=",	B,		Value(U,    0.0f, 16.0f),	Value(U,    0.0f, 16.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	eval_greaterThanEqual_uint,		DE_NULL, DE_NULL, DE_NULL)
   1679 
   1680 		// Equality comparison operators.
   1681 		<< BuiltinOperInfo("equal",				"==",	B,		Value(GT,  -1.0f, 1.0f),	Value(GT,  -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(allEqual))
   1682 		<< BuiltinOperInfo("equal",				"==",	B,		Value(IGT, -5.5f, 4.7f),	Value(IGT, -2.1f, 0.1f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(allEqual))
   1683 		<< BuiltinOperInfo("equal",				"==",	B,		Value(UGT,  0.0f, 8.0f),	Value(UGT,  3.5f, 4.5f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(allEqual))
   1684 		<< BuiltinOperInfo("equal",				"==",	B,		Value(BGT, -2.1f, 2.1f),	Value(BGT, -1.1f, 3.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_NA,	BOOL_GENTYPE_FUNCS(allEqual))
   1685 		<< BuiltinOperInfo("not_equal",			"!=",	B,		Value(GT,  -1.0f, 1.0f),	Value(GT,  -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	FLOAT_GENTYPE_FUNCS(anyNotEqual))
   1686 		<< BuiltinOperInfo("not_equal",			"!=",	B,		Value(IGT, -5.5f, 4.7f),	Value(IGT, -2.1f, 0.1f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	INT_GENTYPE_FUNCS(anyNotEqual))
   1687 		<< BuiltinOperInfo("not_equal",			"!=",	B,		Value(UGT,  0.0f, 8.0f),	Value(UGT,  3.5f, 4.5f),	notUsed,	1.0f, 0.0f,		PRECMASK_ALL,	UINT_GENTYPE_FUNCS(anyNotEqual))
   1688 		<< BuiltinOperInfo("not_equal",			"!=",	B,		Value(BGT, -2.1f, 2.1f),	Value(BGT, -1.1f, 3.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_NA,	BOOL_GENTYPE_FUNCS(anyNotEqual))
   1689 
   1690 		// Logical operators.
   1691 		<< BuiltinOperInfo("logical_and",	"&&",	B,	Value(B, -1.0f, 1.0f),	Value(B, -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_NA,	BOOL_FUNCS(logicalAnd))
   1692 		<< BuiltinOperInfo("logical_or",	"||",	B,	Value(B, -1.0f, 1.0f),	Value(B, -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_NA,	BOOL_FUNCS(logicalOr))
   1693 		<< BuiltinOperInfo("logical_xor",	"^^",	B,	Value(B, -1.0f, 1.0f),	Value(B, -1.0f, 1.0f),	notUsed,	1.0f, 0.0f,		PRECMASK_NA,	BOOL_FUNCS(logicalXor));
   1694 
   1695 	funcInfoGroups.push_back(binaryOpGroup);
   1696 
   1697 	// 8.1 Angle and Trigonometry Functions.
   1698 	funcInfoGroups.push_back(
   1699 		BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.")
   1700 		<< BuiltinFuncInfo("radians",		"radians",		GT,	Value(GT, -1.0f, 1.0f),		notUsed,					notUsed,					25.0f, 0.5f,	PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(radians) )
   1701 		<< BuiltinFuncInfo("degrees",		"degrees",		GT,	Value(GT, -1.0f, 1.0f),		notUsed,					notUsed,					0.04f, 0.5f,	PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(degrees) )
   1702 		<< BuiltinFuncInfo("sin",			"sin",			GT,	Value(GT, -5.0f, 5.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(sin) )
   1703 		<< BuiltinFuncInfo("sin",			"sin",			GT,	Value(GT, -1.5f, 1.5f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_LOWP,				FLOAT_GENTYPE_FUNCS(sin) )
   1704 		<< BuiltinFuncInfo("cos",			"cos",			GT,	Value(GT, -5.0f, 5.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(cos) )
   1705 		<< BuiltinFuncInfo("cos",			"cos",			GT,	Value(GT, -1.5f, 1.5f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_LOWP,				FLOAT_GENTYPE_FUNCS(cos) )
   1706 		<< BuiltinFuncInfo("tan",			"tan",			GT,	Value(GT, -5.0f, 5.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(tan) )
   1707 		<< BuiltinFuncInfo("tan",			"tan",			GT,	Value(GT, -1.5f, 5.5f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_LOWP,				FLOAT_GENTYPE_FUNCS(tan) )
   1708 		<< BuiltinFuncInfo("asin",			"asin",			GT,	Value(GT, -1.0f, 1.0f),		notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(asin) )
   1709 		<< BuiltinFuncInfo("acos",			"acos",			GT,	Value(GT, -1.0f, 1.0f),		notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(acos) )
   1710 		<< BuiltinFuncInfo("atan",			"atan",			GT,	Value(GT, -4.0f, 4.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(atan) )
   1711 		<< BuiltinFuncInfo("atan2",			"atan",			GT,	Value(GT, -4.0f, 4.0f),		Value(GT, 0.5f, 2.0f),		notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(atan2) )
   1712 		<< BuiltinFuncInfo("sinh",			"sinh",			GT,	Value(GT, -5.0f, 5.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(sinh) )
   1713 		<< BuiltinFuncInfo("sinh",			"sinh",			GT,	Value(GT, -1.5f, 1.5f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_LOWP,				FLOAT_GENTYPE_FUNCS(sinh) )
   1714 		<< BuiltinFuncInfo("cosh",			"cosh",			GT,	Value(GT, -5.0f, 5.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(cosh) )
   1715 		<< BuiltinFuncInfo("cosh",			"cosh",			GT,	Value(GT, -1.5f, 1.5f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_LOWP,				FLOAT_GENTYPE_FUNCS(cosh) )
   1716 		<< BuiltinFuncInfo("tanh",			"tanh",			GT,	Value(GT, -5.0f, 5.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(tanh) )
   1717 		<< BuiltinFuncInfo("tanh",			"tanh",			GT,	Value(GT, -1.5f, 5.5f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_LOWP,				FLOAT_GENTYPE_FUNCS(tanh) )
   1718 		<< BuiltinFuncInfo("asinh",			"asinh",		GT,	Value(GT, -1.0f, 1.0f),		notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(asinh) )
   1719 		<< BuiltinFuncInfo("acosh",			"acosh",		GT,	Value(GT, 1.0f, 2.2f),		notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(acosh) )
   1720 		<< BuiltinFuncInfo("atanh",			"atanh",		GT,	Value(GT, -0.99f, 0.99f),	notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(atanh) )
   1721 	);
   1722 
   1723 	// 8.2 Exponential Functions.
   1724 	funcInfoGroups.push_back(
   1725 		BuiltinFuncGroup("exponential", "Exponential function tests")
   1726 		<< BuiltinFuncInfo("pow",			"pow",			GT,	Value(GT, 0.1f, 8.0f),		Value(GT, -4.0f, 2.0f),		notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(pow) )
   1727 		<< BuiltinFuncInfo("exp",			"exp",			GT,	Value(GT, -6.0f, 3.0f),		notUsed,					notUsed,					0.5f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(exp) )
   1728 		<< BuiltinFuncInfo("log",			"log",			GT,	Value(GT, 0.1f, 10.0f),		notUsed,					notUsed,					0.5f, 0.3f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(log) )
   1729 		<< BuiltinFuncInfo("exp2",			"exp2",			GT,	Value(GT, -7.0f, 2.0f),		notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(exp2) )
   1730 		<< BuiltinFuncInfo("log2",			"log2",			GT,	Value(GT, 0.1f, 10.0f),		notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(log2) )
   1731 		<< BuiltinFuncInfo("sqrt",			"sqrt",			GT,	Value(GT, 0.0f, 10.0f),		notUsed,					notUsed,					0.3f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(sqrt) )
   1732 		<< BuiltinFuncInfo("inversesqrt",	"inversesqrt",	GT,	Value(GT, 0.5f, 10.0f),		notUsed,					notUsed,					1.0f, 0.0f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(inverseSqrt) )
   1733 	);
   1734 
   1735 	// 8.3 Common Functions.
   1736 	funcInfoGroups.push_back(
   1737 		BuiltinFuncGroup("common_functions", "Common function tests.")
   1738 		<< BuiltinFuncInfo("abs",			"abs",			GT,	Value(GT, -2.0f, 2.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(abs) )
   1739 		<< BuiltinFuncInfo("sign",			"sign",			GT,	Value(GT, -1.5f, 1.5f),		notUsed,					notUsed,					0.3f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(sign) )
   1740 		<< BuiltinFuncInfo("floor",			"floor",		GT,	Value(GT, -2.5f, 2.5f),		notUsed,					notUsed,					0.2f, 0.7f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(floor) )
   1741 		<< BuiltinFuncInfo("trunc",			"trunc",		GT,	Value(GT, -2.5f, 2.5f),		notUsed,					notUsed,					0.2f, 0.7f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(trunc) )
   1742 		<< BuiltinFuncInfo("round",			"round",		GT,	Value(GT, -2.5f, 2.5f),		notUsed,					notUsed,					0.2f, 0.7f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(roundToEven) )
   1743 		<< BuiltinFuncInfo("roundEven",		"roundEven",	GT,	Value(GT, -2.5f, 2.5f),		notUsed,					notUsed,					0.2f, 0.7f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(roundToEven) )
   1744 		<< BuiltinFuncInfo("ceil",			"ceil",			GT,	Value(GT, -2.5f, 2.5f),		notUsed,					notUsed,					0.2f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(ceil) )
   1745 		<< BuiltinFuncInfo("fract",			"fract",		GT,	Value(GT, -1.5f, 1.5f),		notUsed,					notUsed,					0.8f, 0.1f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(fract) )
   1746 		<< BuiltinFuncInfo("mod",			"mod",			GT,	Value(GT, -2.0f, 2.0f),		Value(GT, 0.9f, 6.0f),		notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(mod) )
   1747 		<< BuiltinFuncInfo("mod",			"mod",			GT,	Value(FV, -2.0f, 2.0f),		Value(F, 0.9f, 6.0f),		notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_VEC_FUNCS(modVecScalar) )
   1748 		<< BuiltinFuncInfo("min",			"min",			GT,	Value(GT, -1.0f, 1.0f),		Value(GT, -1.0f, 1.0f),		notUsed,					0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(min) )
   1749 		<< BuiltinFuncInfo("min",			"min",			GT,	Value(FV, -1.0f, 1.0f),		Value(F, -1.0f, 1.0f),		notUsed,					0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_VEC_FUNCS(minVecScalar) )
   1750 		<< BuiltinFuncInfo("min",			"min",			IGT,Value(IGT, -4.0f, 4.0f),	Value(IGT, -4.0f, 4.0f),	notUsed,					0.125f, 0.5f,	PRECMASK_ALL,				INT_GENTYPE_FUNCS(min) )
   1751 		<< BuiltinFuncInfo("min",			"min",			IGT,Value(IV,  -4.0f, 4.0f),	Value(I, -4.0f, 4.0f),		notUsed,					0.125f, 0.5f,	PRECMASK_ALL,				INT_VEC_FUNCS(minVecScalar) )
   1752 		<< BuiltinFuncInfo("min",			"min",			UGT,Value(UGT, 0.0f, 8.0f),		Value(UGT, 0.0f, 8.0f),		notUsed,					0.125f, 0.0f,	PRECMASK_ALL,				UINT_GENTYPE_FUNCS(min) )
   1753 		<< BuiltinFuncInfo("min",			"min",			UGT,Value(UV,  0.0f, 8.0f),		Value(U, 0.0f, 8.0f),		notUsed,					0.125f, 0.0f,	PRECMASK_ALL,				UINT_VEC_FUNCS(minVecScalar) )
   1754 		<< BuiltinFuncInfo("max",			"max",			GT,	Value(GT, -1.0f, 1.0f),		Value(GT, -1.0f, 1.0f),		notUsed,					0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(max) )
   1755 		<< BuiltinFuncInfo("max",			"max",			GT,	Value(FV, -1.0f, 1.0f),		Value(F, -1.0f, 1.0f),		notUsed,					0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_VEC_FUNCS(maxVecScalar) )
   1756 		<< BuiltinFuncInfo("max",			"max",			IGT,Value(IGT, -4.0f, 4.0f),	Value(IGT, -4.0f, 4.0f),	notUsed,					0.125f, 0.5f,	PRECMASK_ALL,				INT_GENTYPE_FUNCS(max) )
   1757 		<< BuiltinFuncInfo("max",			"max",			IGT,Value(IV,  -4.0f, 4.0f),	Value(I, -4.0f, 4.0f),		notUsed,					0.125f, 0.5f,	PRECMASK_ALL,				INT_VEC_FUNCS(maxVecScalar) )
   1758 		<< BuiltinFuncInfo("max",			"max",			UGT,Value(UGT, 0.0f, 8.0f),		Value(UGT, 0.0f, 8.0f),		notUsed,					0.125f, 0.0f,	PRECMASK_ALL,				UINT_GENTYPE_FUNCS(max) )
   1759 		<< BuiltinFuncInfo("max",			"max",			UGT,Value(UV,  0.0f, 8.0f),		Value(U, 0.0f, 8.0f),		notUsed,					0.125f, 0.0f,	PRECMASK_ALL,				UINT_VEC_FUNCS(maxVecScalar) )
   1760 		<< BuiltinFuncInfo("clamp",			"clamp",		GT,	Value(GT, -1.0f, 1.0f),		Value(GT, -0.5f, 0.5f),		Value(GT, 0.5f, 1.0f),		0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(clamp) )
   1761 		<< BuiltinFuncInfo("clamp",			"clamp",		GT,	Value(FV, -1.0f, 1.0f),		Value(F, -0.5f, 0.5f),		Value(F, 0.5f, 1.0f),		0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_VEC_FUNCS(clampVecScalarScalar) )
   1762 		<< BuiltinFuncInfo("clamp",			"clamp",		IGT,Value(IGT, -4.0f, 4.0f),	Value(IGT, -2.0f, 2.0f),	Value(IGT, 2.0f, 4.0f),		0.125f, 0.5f,	PRECMASK_ALL,				INT_GENTYPE_FUNCS(clamp) )
   1763 		<< BuiltinFuncInfo("clamp",			"clamp",		IGT,Value(IV,  -4.0f, 4.0f),	Value(I, -2.0f, 2.0f),		Value(I, 2.0f, 4.0f),		0.125f, 0.5f,	PRECMASK_ALL,				INT_VEC_FUNCS(clampVecScalarScalar) )
   1764 		<< BuiltinFuncInfo("clamp",			"clamp",		UGT,Value(UGT, 0.0f, 8.0f),		Value(UGT, 2.0f, 6.0f),		Value(UGT, 6.0f, 8.0f),		0.125f, 0.0f,	PRECMASK_ALL,				UINT_GENTYPE_FUNCS(clamp) )
   1765 		<< BuiltinFuncInfo("clamp",			"clamp",		UGT,Value(UV,  0.0f, 8.0f),		Value(U,   2.0f, 6.0f),		Value(U, 6.0f, 8.0f),		0.125f, 0.0f,	PRECMASK_ALL,				UINT_VEC_FUNCS(clampVecScalarScalar) )
   1766 		<< BuiltinFuncInfo("mix",			"mix",			GT,	Value(GT, -1.0f, 1.0f),		Value(GT, -1.0f, 1.0f),		Value(GT, 0.0f, 1.0f),		0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(mix) )
   1767 		<< BuiltinFuncInfo("mix",			"mix",			GT,	Value(FV, -1.0f, 1.0f),		Value(FV, -1.0f, 1.0f),		Value(F, 0.0f, 1.0f),		0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_VEC_FUNCS(mixVecVecScalar) )
   1768 		<< BuiltinFuncInfo("step",			"step",			GT,	Value(GT, -1.0f, 1.0f),		Value(GT, -1.0f, 0.0f),		notUsed,					0.5f, 0.25f,	PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(step) )
   1769 		<< BuiltinFuncInfo("step",			"step",			GT,	Value(F, -1.0f, 1.0f),		Value(FV, -1.0f, 0.0f),		notUsed,					0.5f, 0.25f,	PRECMASK_ALL,				FLOAT_VEC_FUNCS(stepScalarVec) )
   1770 		<< BuiltinFuncInfo("smoothstep",	"smoothstep",	GT,	Value(GT, -0.5f, 0.0f),		Value(GT, 0.1f, 1.0f),		Value(GT, -1.0f, 1.0f),		0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_GENTYPE_FUNCS(smoothStep) )
   1771 		<< BuiltinFuncInfo("smoothstep",	"smoothstep",	GT,	Value(F, -0.5f, 0.0f),		Value(F, 0.1f, 1.0f),		Value(FV, -1.0f, 1.0f),		0.5f, 0.5f,		PRECMASK_ALL,				FLOAT_VEC_FUNCS(smoothStepScalarScalarVec) )
   1772 	);
   1773 
   1774 	// 8.4 Geometric Functions.
   1775 	funcInfoGroups.push_back(
   1776 		BuiltinFuncGroup("geometric", "Geometric function tests.")
   1777 		<< BuiltinFuncInfo("length",		"length",		F,	Value(GT, -5.0f, 5.0f),		notUsed,					notUsed,					0.1f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(length) )
   1778 		<< BuiltinFuncInfo("distance",		"distance",		F,	Value(GT, -5.0f, 5.0f),		Value(GT, -5.0f, 5.0f),		notUsed,					0.1f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(distance) )
   1779 		<< BuiltinFuncInfo("dot",			"dot",			F,	Value(GT, -5.0f, 5.0f),		Value(GT, -5.0f, 5.0f),		notUsed,					0.1f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(dot) )
   1780 		<< BuiltinFuncInfo("cross",			"cross",		V3,	Value(GT, -5.0f, 5.0f),		Value(GT, -5.0f, 5.0f),		notUsed,					0.1f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		DE_NULL, DE_NULL, eval_cross_vec3, DE_NULL )
   1781 		<< BuiltinFuncInfo("normalize",		"normalize",	GT,	Value(GT, 0.1f, 4.0f),		notUsed,					notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(normalize) )
   1782 		<< BuiltinFuncInfo("faceforward",	"faceforward",	GT,	Value(GT, -5.0f, 5.0f),		Value(GT, -5.0f, 5.0f),		Value(GT, -1.0f, 1.0f),		0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(faceForward) )
   1783 		<< BuiltinFuncInfo("reflect",		"reflect",		GT,	Value(GT, -0.8f, -0.5f),	Value(GT, 0.5f, 0.8f),		notUsed,					0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(reflect) )
   1784 		<< BuiltinFuncInfo("refract",		"refract",		GT,	Value(GT, -0.8f, 1.2f),		Value(GT, -1.1f, 0.5f),		Value(F, 0.2f, 1.5f),		0.5f, 0.5f,		PRECMASK_MEDIUMP_HIGHP,		FLOAT_GENTYPE_FUNCS(refract) )
   1785 	);
   1786 
   1787 	// 8.5 Matrix Functions.
   1788 	// separate matrix tests?
   1789 //	funcInfoGroups.push_back(
   1790 //		BuiltinFuncGroup("matrix", "Matrix function tests.")
   1791 //		<< BuiltinFuncInfo("matrixCompMult",	"matrixCompMult",	M, ... )
   1792 //	);
   1793 
   1794 	// 8.6 Vector Relational Functions.
   1795 	funcInfoGroups.push_back(
   1796 		BuiltinFuncGroup("float_compare", "Floating point comparison tests.")
   1797 		<< BuiltinFuncInfo("lessThan",			"lessThan",			BV,	Value(FV, -1.0f, 1.0f),		Value(FV, -1.0f, 1.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	FLOAT_VEC_FUNCS(lessThan) )
   1798 		<< BuiltinFuncInfo("lessThanEqual",		"lessThanEqual",	BV,	Value(FV, -1.0f, 1.0f),		Value(FV, -1.0f, 1.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	FLOAT_VEC_FUNCS(lessThanEqual) )
   1799 		<< BuiltinFuncInfo("greaterThan",		"greaterThan",		BV,	Value(FV, -1.0f, 1.0f),		Value(FV, -1.0f, 1.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	FLOAT_VEC_FUNCS(greaterThan) )
   1800 		<< BuiltinFuncInfo("greaterThanEqual",	"greaterThanEqual",	BV,	Value(FV, -1.0f, 1.0f),		Value(FV, -1.0f, 1.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	FLOAT_VEC_FUNCS(greaterThanEqual) )
   1801 		<< BuiltinFuncInfo("equal",				"equal",			BV,	Value(FV, -1.0f, 1.0f),		Value(FV, -1.0f, 1.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	FLOAT_VEC_FUNCS(equal) )
   1802 		<< BuiltinFuncInfo("notEqual",			"notEqual",			BV,	Value(FV, -1.0f, 1.0f),		Value(FV, -1.0f, 1.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	FLOAT_VEC_FUNCS(notEqual) )
   1803 	);
   1804 
   1805 	funcInfoGroups.push_back(
   1806 		BuiltinFuncGroup("int_compare", "Integer comparison tests.")
   1807 		<< BuiltinFuncInfo("lessThan",			"lessThan",			BV,	Value(IV, -5.2f, 4.9f),		Value(IV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	INT_VEC_FUNCS(lessThan) )
   1808 		<< BuiltinFuncInfo("lessThanEqual",		"lessThanEqual",	BV,	Value(IV, -5.2f, 4.9f),		Value(IV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	INT_VEC_FUNCS(lessThanEqual) )
   1809 		<< BuiltinFuncInfo("greaterThan",		"greaterThan",		BV,	Value(IV, -5.2f, 4.9f),		Value(IV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	INT_VEC_FUNCS(greaterThan) )
   1810 		<< BuiltinFuncInfo("greaterThanEqual",	"greaterThanEqual",	BV,	Value(IV, -5.2f, 4.9f),		Value(IV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	INT_VEC_FUNCS(greaterThanEqual) )
   1811 		<< BuiltinFuncInfo("equal",				"equal",			BV,	Value(IV, -5.2f, 4.9f),		Value(IV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	INT_VEC_FUNCS(equal) )
   1812 		<< BuiltinFuncInfo("notEqual",			"notEqual",			BV,	Value(IV, -5.2f, 4.9f),		Value(IV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_ALL,	INT_VEC_FUNCS(notEqual) )
   1813 	);
   1814 
   1815 	funcInfoGroups.push_back(
   1816 		BuiltinFuncGroup("bool_compare", "Boolean comparison tests.")
   1817 		<< BuiltinFuncInfo("equal",				"equal",			BV,	Value(BV, -5.2f, 4.9f),		Value(BV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_NA,	BOOL_VEC_FUNCS(equal) )
   1818 		<< BuiltinFuncInfo("notEqual",			"notEqual",			BV,	Value(BV, -5.2f, 4.9f),		Value(BV, -5.0f, 5.0f),	notUsed, 1.0f, 0.0f, PRECMASK_NA,	BOOL_VEC_FUNCS(notEqual) )
   1819 		<< BuiltinFuncInfo("any",				"any",				B,	Value(BV, -1.0f, 0.3f),		notUsed,				notUsed, 1.0f, 0.0f, PRECMASK_NA,	BOOL_VEC_FUNCS(any) )
   1820 		<< BuiltinFuncInfo("all",				"all",				B,	Value(BV, -0.3f, 1.0f),		notUsed,				notUsed, 1.0f, 0.0f, PRECMASK_NA,	BOOL_VEC_FUNCS(all) )
   1821 		<< BuiltinFuncInfo("not",				"not",				BV,	Value(BV, -1.0f, 1.0f),		notUsed,				notUsed, 1.0f, 0.0f, PRECMASK_NA,	BOOL_VEC_FUNCS(boolNot) )
   1822 	);
   1823 
   1824 	static const ShaderType s_shaderTypes[] =
   1825 	{
   1826 		SHADERTYPE_VERTEX,
   1827 		SHADERTYPE_FRAGMENT
   1828 	};
   1829 
   1830 	static const DataType s_floatTypes[] =
   1831 	{
   1832 		TYPE_FLOAT,
   1833 		TYPE_FLOAT_VEC2,
   1834 		TYPE_FLOAT_VEC3,
   1835 		TYPE_FLOAT_VEC4
   1836 	};
   1837 
   1838 	static const DataType s_intTypes[] =
   1839 	{
   1840 		TYPE_INT,
   1841 		TYPE_INT_VEC2,
   1842 		TYPE_INT_VEC3,
   1843 		TYPE_INT_VEC4
   1844 	};
   1845 
   1846 	static const DataType s_uintTypes[] =
   1847 	{
   1848 		TYPE_UINT,
   1849 		TYPE_UINT_VEC2,
   1850 		TYPE_UINT_VEC3,
   1851 		TYPE_UINT_VEC4
   1852 	};
   1853 
   1854 	static const DataType s_boolTypes[] =
   1855 	{
   1856 		TYPE_BOOL,
   1857 		TYPE_BOOL_VEC2,
   1858 		TYPE_BOOL_VEC3,
   1859 		TYPE_BOOL_VEC4
   1860 	};
   1861 
   1862 	for (int outerGroupNdx = 0; outerGroupNdx < (int)funcInfoGroups.size(); outerGroupNdx++)
   1863 	{
   1864 		// Create outer group.
   1865 		const BuiltinFuncGroup& outerGroupInfo = funcInfoGroups[outerGroupNdx];
   1866 		TestCaseGroup* outerGroup = new TestCaseGroup(m_context, outerGroupInfo.name, outerGroupInfo.description);
   1867 		addChild(outerGroup);
   1868 
   1869 		// Only create new group if name differs from previous one.
   1870 		TestCaseGroup* innerGroup = DE_NULL;
   1871 
   1872 		for (int funcInfoNdx = 0; funcInfoNdx < (int)outerGroupInfo.funcInfos.size(); funcInfoNdx++)
   1873 		{
   1874 			const BuiltinFuncInfo&	funcInfo 		= outerGroupInfo.funcInfos[funcInfoNdx];
   1875 			const char*				shaderFuncName	= funcInfo.shaderFuncName;
   1876 			bool					isBoolCase		= (funcInfo.precisionMask == PRECMASK_NA);
   1877 			bool					isBoolOut		= (funcInfo.outValue & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0;
   1878 			bool					isIntOut		= (funcInfo.outValue & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0;
   1879 			bool					isUintOut		= (funcInfo.outValue & (VALUE_UINT | VALUE_UINT_VEC | VALUE_UINT_GENTYPE)) != 0;
   1880 			bool					isFloatOut		= !isBoolOut && !isIntOut && !isUintOut;
   1881 
   1882 			if (!innerGroup || (string(innerGroup->getName()) != funcInfo.caseName))
   1883 			{
   1884 				string groupDesc = string("Built-in function ") + shaderFuncName + "() tests.";
   1885 				innerGroup = new TestCaseGroup(m_context, funcInfo.caseName, groupDesc.c_str());
   1886 				outerGroup->addChild(innerGroup);
   1887 			}
   1888 
   1889 			for (int inScalarSize = 1; inScalarSize <= 4; inScalarSize++)
   1890 			{
   1891 				int			outScalarSize	= ((funcInfo.outValue == VALUE_FLOAT) || (funcInfo.outValue == VALUE_BOOL)) ? 1 : inScalarSize; // \todo [petri] Int.
   1892 				DataType	outDataType		= isFloatOut	? s_floatTypes[outScalarSize - 1]
   1893 											: isIntOut		? s_intTypes[outScalarSize - 1]
   1894 											: isUintOut		? s_uintTypes[outScalarSize - 1]
   1895 											: isBoolOut		? s_boolTypes[outScalarSize - 1]
   1896 											: TYPE_LAST;
   1897 
   1898 				ShaderEvalFunc evalFunc = DE_NULL;
   1899 				if      (inScalarSize == 1)	evalFunc = funcInfo.evalFuncScalar;
   1900 				else if (inScalarSize == 2)	evalFunc = funcInfo.evalFuncVec2;
   1901 				else if (inScalarSize == 3)	evalFunc = funcInfo.evalFuncVec3;
   1902 				else if (inScalarSize == 4)	evalFunc = funcInfo.evalFuncVec4;
   1903 				else DE_ASSERT(false);
   1904 
   1905 				// Skip if no valid eval func.
   1906 				// \todo [petri] Better check for V3 only etc. cases?
   1907 				if (evalFunc == DE_NULL)
   1908 					continue;
   1909 
   1910 				for (int precision = 0; precision < PRECISION_LAST; precision++)
   1911 				{
   1912 					if ((funcInfo.precisionMask & (1<<precision)) ||
   1913 						(funcInfo.precisionMask == PRECMASK_NA && precision == PRECISION_MEDIUMP)) // use mediump interpolators for booleans
   1914 					{
   1915 						const char*	precisionStr	= getPrecisionName((Precision)precision);
   1916 						string		precisionPrefix	= isBoolCase ? "" : (string(precisionStr) + "_");
   1917 
   1918 						for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
   1919 						{
   1920 							ShaderType		shaderType		= s_shaderTypes[shaderTypeNdx];
   1921 							ShaderDataSpec	shaderSpec;
   1922 							const char*		shaderTypeName	= getShaderTypeName(shaderType);
   1923 							bool			isVertexCase	= (ShaderType)shaderType == SHADERTYPE_VERTEX;
   1924 							bool			isUnaryOp		= (funcInfo.input1.valueType == VALUE_NONE);
   1925 
   1926 							// \note Data type names will be added to description and name in a following loop.
   1927 							string desc	= string("Built-in function ") + shaderFuncName + "(";
   1928 							string name = precisionPrefix;
   1929 
   1930 							// Generate shader op.
   1931 							string shaderOp = string("res = ");
   1932 
   1933 							// Setup shader data info.
   1934 							shaderSpec.numInputs		= 0;
   1935 							shaderSpec.precision		= isBoolCase ? PRECISION_LAST : (Precision)precision;
   1936 							shaderSpec.output			= outDataType;
   1937 							shaderSpec.resultScale		= funcInfo.resultScale;
   1938 							shaderSpec.resultBias		= funcInfo.resultBias;
   1939 							shaderSpec.referenceScale	= funcInfo.referenceScale;
   1940 							shaderSpec.referenceBias	= funcInfo.referenceBias;
   1941 
   1942 							if (funcInfo.type == OPERATOR)
   1943 							{
   1944 								if (isUnaryOp && funcInfo.isUnaryPrefix)
   1945 									shaderOp += shaderFuncName;
   1946 							}
   1947 							else if (funcInfo.type == FUNCTION)
   1948 								shaderOp += string(shaderFuncName) + "(";
   1949 							else // SIDE_EFFECT_OPERATOR
   1950 								shaderOp += "in0;\n\t";
   1951 
   1952 							for (int inputNdx = 0; inputNdx < MAX_INPUTS; inputNdx++)
   1953 							{
   1954 								const Value&	prevV			= (inputNdx == 1) ? funcInfo.input0 : (inputNdx == 2) ? funcInfo.input1 : funcInfo.input2;
   1955 								const Value&	v				= (inputNdx == 0) ? funcInfo.input0 : (inputNdx == 1) ? funcInfo.input1 : funcInfo.input2;
   1956 
   1957 								if (v.valueType == VALUE_NONE)
   1958 									continue; // Skip unused input.
   1959 
   1960 								int				prevInScalarSize	= isScalarType(prevV.valueType) ? 1 : inScalarSize;
   1961 								DataType		prevInDataType		= isFloatType(prevV.valueType)	? s_floatTypes[prevInScalarSize - 1]
   1962 																	: isIntType(prevV.valueType)	? s_intTypes[prevInScalarSize - 1]
   1963 																	: isUintType(prevV.valueType)	? s_uintTypes[prevInScalarSize - 1]
   1964 																	: isBoolType(prevV.valueType)	? s_boolTypes[prevInScalarSize - 1]
   1965 																	: TYPE_LAST;
   1966 
   1967 								int				curInScalarSize		= isScalarType(v.valueType) ? 1 : inScalarSize;
   1968 								DataType		curInDataType		= isFloatType(v.valueType)	? s_floatTypes[curInScalarSize - 1]
   1969 																	: isIntType(v.valueType)	? s_intTypes[curInScalarSize - 1]
   1970 																	: isUintType(v.valueType)	? s_uintTypes[curInScalarSize - 1]
   1971 																	: isBoolType(v.valueType)	? s_boolTypes[curInScalarSize - 1]
   1972 																	: TYPE_LAST;
   1973 
   1974 								// Write input type(s) to case description and name.
   1975 
   1976 								if (inputNdx > 0)
   1977 									desc += ", ";
   1978 
   1979 								desc += getDataTypeName(curInDataType);
   1980 
   1981 								if (inputNdx == 0 || prevInDataType != curInDataType) // \note Only write input type to case name if different from previous input type (avoid overly long names).
   1982 									name += string("") + getDataTypeName(curInDataType) + "_";
   1983 
   1984 								// Generate op input source.
   1985 
   1986 								if (funcInfo.type == OPERATOR || funcInfo.type == FUNCTION)
   1987 								{
   1988 									if (inputNdx != 0)
   1989 									{
   1990 										if (funcInfo.type == OPERATOR && !isUnaryOp)
   1991 											shaderOp += " " + string(shaderFuncName) + " ";
   1992 										else
   1993 											shaderOp += ", ";
   1994 									}
   1995 
   1996 									shaderOp += "in" + de::toString(inputNdx);
   1997 
   1998 									if (funcInfo.type == OPERATOR && isUnaryOp && !funcInfo.isUnaryPrefix)
   1999 										shaderOp += string(shaderFuncName);
   2000 								}
   2001 								else
   2002 								{
   2003 									DE_ASSERT(funcInfo.type == SIDE_EFFECT_OPERATOR);
   2004 
   2005 									if (inputNdx != 0 || (isUnaryOp && funcInfo.isUnaryPrefix))
   2006 										shaderOp += string("") + (isUnaryOp ? "" : " ") + shaderFuncName + (isUnaryOp ? "" : " ");
   2007 
   2008 									shaderOp += inputNdx == 0 ? "res" : "in" + de::toString(inputNdx); // \note in0 has already been assigned to res, so start from in1.
   2009 
   2010 									if (isUnaryOp && !funcInfo.isUnaryPrefix)
   2011 										shaderOp += shaderFuncName;
   2012 								}
   2013 
   2014 								// Fill in shader info.
   2015 								shaderSpec.inputs[shaderSpec.numInputs++] = ShaderValue(curInDataType, v.rangeMin, v.rangeMax);
   2016 							}
   2017 
   2018 							if (funcInfo.type == FUNCTION)
   2019 								shaderOp += ")";
   2020 
   2021 							shaderOp += ";";
   2022 
   2023 							desc += ").";
   2024 							name += shaderTypeName;
   2025 
   2026 							// Create the test case.
   2027 							innerGroup->addChild(new ShaderOperatorCase(m_context, name.c_str(), desc.c_str(), isVertexCase, evalFunc, shaderOp, shaderSpec));
   2028 						}
   2029 					}
   2030 				}
   2031 			}
   2032 		}
   2033 	}
   2034 
   2035 	// The ?: selection operator.
   2036 
   2037 	static const struct
   2038 	{
   2039 		DataType		type; // The type of "Y" and "Z" operands in "X ? Y : Z" (X is always bool).
   2040 		ShaderEvalFunc	evalFunc;
   2041 	} s_selectionInfo[] =
   2042 	{
   2043 		{ TYPE_FLOAT,		eval_selection_float	},
   2044 		{ TYPE_FLOAT_VEC2,	eval_selection_vec2		},
   2045 		{ TYPE_FLOAT_VEC3,	eval_selection_vec3		},
   2046 		{ TYPE_FLOAT_VEC4,	eval_selection_vec4		},
   2047 		{ TYPE_INT,			eval_selection_int		},
   2048 		{ TYPE_INT_VEC2,	eval_selection_ivec2	},
   2049 		{ TYPE_INT_VEC3,	eval_selection_ivec3	},
   2050 		{ TYPE_INT_VEC4,	eval_selection_ivec4	},
   2051 		{ TYPE_UINT,		eval_selection_uint		},
   2052 		{ TYPE_UINT_VEC2,	eval_selection_uvec2	},
   2053 		{ TYPE_UINT_VEC3,	eval_selection_uvec3	},
   2054 		{ TYPE_UINT_VEC4,	eval_selection_uvec4	},
   2055 		{ TYPE_BOOL,		eval_selection_bool		},
   2056 		{ TYPE_BOOL_VEC2,	eval_selection_bvec2	},
   2057 		{ TYPE_BOOL_VEC3,	eval_selection_bvec3	},
   2058 		{ TYPE_BOOL_VEC4,	eval_selection_bvec4	}
   2059 	};
   2060 
   2061 	TestCaseGroup* selectionGroup = new TestCaseGroup(m_context, "selection", "Selection operator tests");
   2062 	addChild(selectionGroup);
   2063 
   2064 	for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_selectionInfo); typeNdx++)
   2065 	{
   2066 		DataType		curType			= s_selectionInfo[typeNdx].type;
   2067 		ShaderEvalFunc	evalFunc		= s_selectionInfo[typeNdx].evalFunc;
   2068 		bool			isBoolCase		= isDataTypeBoolOrBVec(curType);
   2069 		bool			isFloatCase		= isDataTypeFloatOrVec(curType);
   2070 		bool			isIntCase		= isDataTypeIntOrIVec(curType);
   2071 		bool			isUintCase		= isDataTypeUintOrUVec(curType);
   2072 		const char*		dataTypeStr		= getDataTypeName(curType);
   2073 
   2074 		DE_ASSERT(isBoolCase || isFloatCase || isIntCase || isUintCase);
   2075 		DE_UNREF(isIntCase);
   2076 
   2077 		for (int precision = 0; precision < (int)PRECISION_LAST; precision++)
   2078 		{
   2079 			if (isBoolCase && precision != PRECISION_MEDIUMP) // Use mediump interpolators for booleans.
   2080 				continue;
   2081 
   2082 			const char*	precisionStr	= getPrecisionName((Precision)precision);
   2083 			string		precisionPrefix	= isBoolCase ? "" : (string(precisionStr) + "_");
   2084 
   2085 			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
   2086 			{
   2087 				ShaderType		shaderType		= s_shaderTypes[shaderTypeNdx];
   2088 				ShaderDataSpec	shaderSpec;
   2089 				const char*		shaderTypeName	= getShaderTypeName(shaderType);
   2090 				bool			isVertexCase	= (ShaderType)shaderType == SHADERTYPE_VERTEX;
   2091 
   2092 				string name	= precisionPrefix + dataTypeStr + "_" + shaderTypeName;
   2093 
   2094 				shaderSpec.numInputs		= 3;
   2095 				shaderSpec.precision		= isBoolCase ? PRECISION_LAST : (Precision)precision;
   2096 				shaderSpec.output			= curType;
   2097 				shaderSpec.resultScale		= isBoolCase ? 1.0f : isFloatCase ? 0.5f : isUintCase ? 0.5f : 0.1f;
   2098 				shaderSpec.resultBias		= isBoolCase ? 0.0f : isFloatCase ? 0.5f : isUintCase ? 0.0f : 0.5f;
   2099 				shaderSpec.referenceScale	= shaderSpec.resultScale;
   2100 				shaderSpec.referenceBias	= shaderSpec.resultBias;
   2101 
   2102 				float rangeMin = isBoolCase ? -1.0f : isFloatCase ? -1.0f : isUintCase ? 0.0f : -5.0f;
   2103 				float rangeMax = isBoolCase ?  1.0f : isFloatCase ?  1.0f : isUintCase ? 2.0f :  5.0f;
   2104 
   2105 				shaderSpec.inputs[0] = ShaderValue(TYPE_BOOL, -1.0f, 1.0f);
   2106 				shaderSpec.inputs[1] = ShaderValue(curType, rangeMin, rangeMax);
   2107 				shaderSpec.inputs[2] = ShaderValue(curType, rangeMin, rangeMax);
   2108 
   2109 				selectionGroup->addChild(new ShaderOperatorCase(m_context, name.c_str(), "", isVertexCase, evalFunc, "res = in0 ? in1 : in2;", shaderSpec));
   2110 			}
   2111 		}
   2112 	}
   2113 
   2114 	// The sequence operator (comma).
   2115 
   2116 	TestCaseGroup* sequenceGroup = new TestCaseGroup(m_context, "sequence", "Sequence operator tests");
   2117 	addChild(sequenceGroup);
   2118 
   2119 	TestCaseGroup* sequenceNoSideEffGroup = new TestCaseGroup(m_context, "no_side_effects", "Sequence tests without side-effects");
   2120 	TestCaseGroup* sequenceSideEffGroup = new TestCaseGroup(m_context, "side_effects", "Sequence tests with side-effects");
   2121 	sequenceGroup->addChild(sequenceNoSideEffGroup);
   2122 	sequenceGroup->addChild(sequenceSideEffGroup);
   2123 
   2124 	static const struct
   2125 	{
   2126 		bool			containsSideEffects;
   2127 		const char*		caseName;
   2128 		const char*		expressionStr;
   2129 		int				numInputs;
   2130 		DataType		inputTypes[MAX_INPUTS];
   2131 		DataType		resultType;
   2132 		ShaderEvalFunc	evalFunc;
   2133 	} s_sequenceCases[] =
   2134 	{
   2135 		{ false,	"vec4",					"in0, in2 + in1, in1 + in0",							3,	{ TYPE_FLOAT_VEC4,	TYPE_FLOAT_VEC4,	TYPE_FLOAT_VEC4	},	TYPE_FLOAT_VEC4,	evalSequenceNoSideEffCase0 },
   2136 		{ false,	"float_uint",			"in0 + in2, in1 + in1",									3,	{ TYPE_FLOAT,		TYPE_UINT,			TYPE_FLOAT		},	TYPE_UINT,			evalSequenceNoSideEffCase1 },
   2137 		{ false,	"bool_vec2",			"in0 && in1, in0, ivec2(vec2(in0) + in2)",				3,	{ TYPE_BOOL,		TYPE_BOOL,			TYPE_FLOAT_VEC2	},	TYPE_INT_VEC2,		evalSequenceNoSideEffCase2 },
   2138 		{ false,	"vec4_ivec4_bvec4",		"in0 + vec4(in1), in2, in1",							3,	{ TYPE_FLOAT_VEC4,	TYPE_INT_VEC4,		TYPE_BOOL_VEC4	},	TYPE_INT_VEC4,		evalSequenceNoSideEffCase3 },
   2139 
   2140 		{ true,		"vec4",					"in0++, in1 = in0 + in2, in2 = in1",					3,	{ TYPE_FLOAT_VEC4,	TYPE_FLOAT_VEC4,	TYPE_FLOAT_VEC4	},	TYPE_FLOAT_VEC4,	evalSequenceSideEffCase0 },
   2141 		{ true,		"float_uint",			"in1++, in0 = float(in1), in1 = uint(in0 + in2)",		3,	{ TYPE_FLOAT,		TYPE_UINT,			TYPE_FLOAT		},	TYPE_UINT,			evalSequenceSideEffCase1 },
   2142 		{ true,		"bool_vec2",			"in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)",	3,	{ TYPE_BOOL,		TYPE_BOOL,			TYPE_FLOAT_VEC2	},	TYPE_INT_VEC2,		evalSequenceSideEffCase2 },
   2143 		{ true,		"vec4_ivec4_bvec4",		"in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++",	3,	{ TYPE_FLOAT_VEC4,	TYPE_INT_VEC4,		TYPE_BOOL_VEC4	},	TYPE_INT_VEC4,		evalSequenceSideEffCase3 }
   2144 	};
   2145 
   2146 	for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_sequenceCases); caseNdx++)
   2147 	{
   2148 		for (int precision = 0; precision < (int)PRECISION_LAST; precision++)
   2149 		{
   2150 			for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
   2151 			{
   2152 				ShaderType		shaderType		= s_shaderTypes[shaderTypeNdx];
   2153 				ShaderDataSpec	shaderSpec;
   2154 				const char*		shaderTypeName	= getShaderTypeName(shaderType);
   2155 				bool			isVertexCase	= (ShaderType)shaderType == SHADERTYPE_VERTEX;
   2156 
   2157 				string name	= string("") + getPrecisionName((Precision)precision) + "_" + s_sequenceCases[caseNdx].caseName + "_" + shaderTypeName;
   2158 
   2159 				shaderSpec.numInputs		= s_sequenceCases[caseNdx].numInputs;
   2160 				shaderSpec.precision		= (Precision)precision;
   2161 				shaderSpec.output			= s_sequenceCases[caseNdx].resultType;
   2162 				shaderSpec.resultScale		= 0.5f;
   2163 				shaderSpec.resultBias		= 0.0f;
   2164 				shaderSpec.referenceScale	= shaderSpec.resultScale;
   2165 				shaderSpec.referenceBias	= shaderSpec.resultBias;
   2166 
   2167 				for (int inputNdx = 0; inputNdx < s_sequenceCases[caseNdx].numInputs; inputNdx++)
   2168 				{
   2169 					DataType	type		= s_sequenceCases[caseNdx].inputTypes[inputNdx];
   2170 					float		rangeMin	= isDataTypeFloatOrVec(type) ? -0.5f : isDataTypeIntOrIVec(type) ? -2.0f : isDataTypeUintOrUVec(type) ? 0.0f : -1.0f;
   2171 					float		rangeMax	= isDataTypeFloatOrVec(type) ?  0.5f : isDataTypeIntOrIVec(type) ?  2.0f : isDataTypeUintOrUVec(type) ? 2.0f :  1.0f;
   2172 
   2173 					shaderSpec.inputs[inputNdx] = ShaderValue(type, rangeMin, rangeMax);
   2174 				}
   2175 
   2176 				string expression = string("") + "res = (" + s_sequenceCases[caseNdx].expressionStr + ");";
   2177 
   2178 				TestCaseGroup* group = s_sequenceCases[caseNdx].containsSideEffects ? sequenceSideEffGroup : sequenceNoSideEffGroup;
   2179 				group->addChild(new ShaderOperatorCase(m_context, name.c_str(), "", isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression.c_str(), shaderSpec));
   2180 			}
   2181 		}
   2182 	}
   2183 }
   2184 
   2185 } // Functional
   2186 } // gles3
   2187 } // deqp
   2188