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