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