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