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