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