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