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