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