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::ostringstream;
45 using std::pair;
46 using std::string;
47 using std::vector;
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::clamp;
61 using de::max;
62 using de::min;
63
64 // \note VS2013 gets confused without these
65 using tcu::acosh;
66 using tcu::asinh;
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)
73 {
74 return deFloatAbs(v);
75 }
76
logicalAnd(bool a,bool b)77 inline bool logicalAnd(bool a, bool b)
78 {
79 return (a && b);
80 }
logicalOr(bool a,bool b)81 inline bool logicalOr(bool a, bool b)
82 {
83 return (a || b);
84 }
logicalXor(bool a,bool b)85 inline bool logicalXor(bool a, bool b)
86 {
87 return (a != b);
88 }
89
90 // \note stdlib.h defines div() that is not compatible with the macros.
91 template <typename T>
div(T a,T b)92 inline T div(T a, T b)
93 {
94 return a / b;
95 }
96
97 template <typename T>
leftShift(T value,int amount)98 inline T leftShift(T value, int amount)
99 {
100 return value << amount;
101 }
102
rightShift(uint32_t value,int amount)103 inline uint32_t rightShift(uint32_t value, int amount)
104 {
105 return value >> amount;
106 }
rightShift(int value,int amount)107 inline int rightShift(int value, int amount)
108 {
109 return (value >> amount) | (value >= 0 ? 0 : ~(~0U >> amount));
110 } // \note Arithmetic shift.
111
112 template <typename T, int Size>
leftShift(const Vector<T,Size> & value,const Vector<int,Size> & amount)113 Vector<T, Size> leftShift(const Vector<T, Size> &value, const Vector<int, Size> &amount)
114 {
115 Vector<T, Size> result;
116 for (int i = 0; i < Size; i++)
117 result[i] = leftShift(value[i], amount[i]);
118 return result;
119 }
120
121 template <typename T, int Size>
rightShift(const Vector<T,Size> & value,const Vector<int,Size> & amount)122 Vector<T, Size> rightShift(const Vector<T, Size> &value, const Vector<int, Size> &amount)
123 {
124 Vector<T, Size> result;
125 for (int i = 0; i < Size; i++)
126 result[i] = rightShift(value[i], amount[i]);
127 return result;
128 }
129
130 template <typename T, int Size>
leftShiftVecScalar(const Vector<T,Size> & value,int amount)131 Vector<T, Size> leftShiftVecScalar(const Vector<T, Size> &value, int amount)
132 {
133 return leftShift(value, Vector<int, Size>(amount));
134 }
135 template <typename T, int Size>
rightShiftVecScalar(const Vector<T,Size> & value,int amount)136 Vector<T, Size> rightShiftVecScalar(const Vector<T, Size> &value, int amount)
137 {
138 return rightShift(value, Vector<int, Size>(amount));
139 }
140
141 template <typename T, int Size>
minVecScalar(const Vector<T,Size> & v,T s)142 inline Vector<T, Size> minVecScalar(const Vector<T, Size> &v, T s)
143 {
144 Vector<T, Size> res;
145 for (int i = 0; i < Size; i++)
146 res[i] = min(v[i], s);
147 return res;
148 }
149
150 template <typename T, int Size>
maxVecScalar(const Vector<T,Size> & v,T s)151 inline Vector<T, Size> maxVecScalar(const Vector<T, Size> &v, T s)
152 {
153 Vector<T, Size> res;
154 for (int i = 0; i < Size; i++)
155 res[i] = max(v[i], s);
156 return res;
157 }
158
159 template <typename T, int Size>
clampVecScalarScalar(const Vector<T,Size> & v,T s0,T s1)160 inline Vector<T, Size> clampVecScalarScalar(const Vector<T, Size> &v, T s0, T s1)
161 {
162 Vector<T, Size> res;
163 for (int i = 0; i < Size; i++)
164 res[i] = clamp(v[i], s0, s1);
165 return res;
166 }
167
168 template <typename T, int Size>
mixVecVecScalar(const Vector<T,Size> & v0,const Vector<T,Size> & v1,T s)169 inline Vector<T, Size> mixVecVecScalar(const Vector<T, Size> &v0, const Vector<T, Size> &v1, T s)
170 {
171 Vector<T, Size> res;
172 for (int i = 0; i < Size; i++)
173 res[i] = mix(v0[i], v1[i], s);
174 return res;
175 }
176
177 template <typename T, int Size>
stepScalarVec(T s,const Vector<T,Size> & v)178 inline Vector<T, Size> stepScalarVec(T s, const Vector<T, Size> &v)
179 {
180 Vector<T, Size> res;
181 for (int i = 0; i < Size; i++)
182 res[i] = step(s, v[i]);
183 return res;
184 }
185
186 template <typename T, int Size>
smoothStepScalarScalarVec(T s0,T s1,const Vector<T,Size> & v)187 inline Vector<T, Size> smoothStepScalarScalarVec(T s0, T s1, const Vector<T, Size> &v)
188 {
189 Vector<T, Size> res;
190 for (int i = 0; i < Size; i++)
191 res[i] = smoothStep(s0, s1, v[i]);
192 return res;
193 }
194
addOne(float v)195 inline float addOne(float v)
196 {
197 return v + 1.0f;
198 }
subOne(float v)199 inline float subOne(float v)
200 {
201 return v - 1.0f;
202 }
addOne(int v)203 inline int addOne(int v)
204 {
205 return v + 1;
206 }
subOne(int v)207 inline int subOne(int v)
208 {
209 return v - 1;
210 }
addOne(uint32_t v)211 inline uint32_t addOne(uint32_t v)
212 {
213 return v + 1;
214 }
subOne(uint32_t v)215 inline uint32_t subOne(uint32_t v)
216 {
217 return v - 1;
218 }
219
220 template <int Size>
addOne(const Vector<float,Size> & v)221 inline Vector<float, Size> addOne(const Vector<float, Size> &v)
222 {
223 return v + 1.0f;
224 }
225 template <int Size>
subOne(const Vector<float,Size> & v)226 inline Vector<float, Size> subOne(const Vector<float, Size> &v)
227 {
228 return v - 1.0f;
229 }
230 template <int Size>
addOne(const Vector<int,Size> & v)231 inline Vector<int, Size> addOne(const Vector<int, Size> &v)
232 {
233 return v + 1;
234 }
235 template <int Size>
subOne(const Vector<int,Size> & v)236 inline Vector<int, Size> subOne(const Vector<int, Size> &v)
237 {
238 return v - 1;
239 }
240 template <int Size>
addOne(const Vector<uint32_t,Size> & v)241 inline Vector<uint32_t, Size> addOne(const Vector<uint32_t, Size> &v)
242 {
243 return v + 1U;
244 }
245 template <int Size>
subOne(const Vector<uint32_t,Size> & v)246 inline Vector<uint32_t, Size> subOne(const Vector<uint32_t, Size> &v)
247 {
248 return (v.asInt() - 1).asUint();
249 }
250
251 template <typename T>
selection(bool cond,T a,T b)252 inline T selection(bool cond, T a, T b)
253 {
254 return cond ? a : b;
255 }
256
257 // Vec-scalar and scalar-vec binary operators.
258
259 // \note This one is done separately due to how the overloaded minus operator is implemented for vector-scalar operands.
260 template <int Size>
subVecScalar(const Vector<uint32_t,Size> & v,uint32_t s)261 inline Vector<uint32_t, Size> subVecScalar(const Vector<uint32_t, Size> &v, uint32_t s)
262 {
263 return (v.asInt() - (int)s).asUint();
264 }
265
266 template <typename T, int Size>
addVecScalar(const Vector<T,Size> & v,T s)267 inline Vector<T, Size> addVecScalar(const Vector<T, Size> &v, T s)
268 {
269 return v + s;
270 }
271
272 // Specialize add, sub, and mul integer operations to use 64bit to avoid undefined signed integer overflows.
add(int a,int b)273 inline int add(int a, int b)
274 {
275 return static_cast<int>(static_cast<int64_t>(a) + static_cast<int64_t>(b));
276 }
sub(int a,int b)277 inline int sub(int a, int b)
278 {
279 return static_cast<int>(static_cast<int64_t>(a) - static_cast<int64_t>(b));
280 }
mul(int a,int b)281 inline int mul(int a, int b)
282 {
283 return static_cast<int>(static_cast<int64_t>(a) * static_cast<int64_t>(b));
284 }
285
add(uint32_t a,uint32_t b)286 inline uint32_t add(uint32_t a, uint32_t b)
287 {
288 return a + b;
289 }
sub(uint32_t a,uint32_t b)290 inline uint32_t sub(uint32_t a, uint32_t b)
291 {
292 return a - b;
293 }
mul(uint32_t a,uint32_t b)294 inline uint32_t mul(uint32_t a, uint32_t b)
295 {
296 return a * b;
297 }
298
299 #define DECLARE_IVEC_BINARY_FUNC(OP_NAME) \
300 template <int Size> \
301 inline Vector<int, Size> OP_NAME(const Vector<int, Size> &a, const Vector<int, Size> &b) \
302 { \
303 Vector<int, Size> res; \
304 for (int i = 0; i < Size; i++) \
305 res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i]); \
306 return res; \
307 }
308
309 #define DECLARE_IVEC_INT_BINARY_FUNC(OP_NAME) \
310 template <int Size> \
311 inline Vector<int, Size> OP_NAME##VecScalar(const Vector<int, Size> &v, int s) \
312 { \
313 Vector<int, Size> ret; \
314 for (int i = 0; i < Size; i++) \
315 ret[i] = OP_NAME(v.m_data[i], s); \
316 return ret; \
317 };
318
319 #define DECLARE_INT_IVEC_BINARY_FUNC(OP_NAME) \
320 template <int Size> \
321 inline Vector<int, Size> OP_NAME##ScalarVec(int s, const Vector<int, Size> &v) \
322 { \
323 Vector<int, Size> ret; \
324 for (int i = 0; i < Size; i++) \
325 ret[i] = OP_NAME(s, v.m_data[i]); \
326 return ret; \
327 };
328
329 DECLARE_IVEC_BINARY_FUNC(add)
DECLARE_IVEC_BINARY_FUNC(sub)330 DECLARE_IVEC_BINARY_FUNC(sub)
331 DECLARE_IVEC_BINARY_FUNC(mul)
332 DECLARE_IVEC_INT_BINARY_FUNC(add)
333 DECLARE_IVEC_INT_BINARY_FUNC(sub)
334 DECLARE_IVEC_INT_BINARY_FUNC(mul)
335 DECLARE_INT_IVEC_BINARY_FUNC(add)
336 DECLARE_INT_IVEC_BINARY_FUNC(sub)
337 DECLARE_INT_IVEC_BINARY_FUNC(mul)
338
339 template <typename T, int Size>
340 inline Vector<T, Size> subVecScalar(const Vector<T, Size> &v, T s)
341 {
342 return v - s;
343 }
344 template <typename T, int Size>
mulVecScalar(const Vector<T,Size> & v,T s)345 inline Vector<T, Size> mulVecScalar(const Vector<T, Size> &v, T s)
346 {
347 return v * s;
348 }
349 template <typename T, int Size>
divVecScalar(const Vector<T,Size> & v,T s)350 inline Vector<T, Size> divVecScalar(const Vector<T, Size> &v, T s)
351 {
352 return v / s;
353 }
354 template <typename T, int Size>
modVecScalar(const Vector<T,Size> & v,T s)355 inline Vector<T, Size> modVecScalar(const Vector<T, Size> &v, T s)
356 {
357 return mod(v, Vector<T, Size>(s));
358 }
359 template <typename T, int Size>
bitwiseAndVecScalar(const Vector<T,Size> & v,T s)360 inline Vector<T, Size> bitwiseAndVecScalar(const Vector<T, Size> &v, T s)
361 {
362 return bitwiseAnd(v, Vector<T, Size>(s));
363 }
364 template <typename T, int Size>
bitwiseOrVecScalar(const Vector<T,Size> & v,T s)365 inline Vector<T, Size> bitwiseOrVecScalar(const Vector<T, Size> &v, T s)
366 {
367 return bitwiseOr(v, Vector<T, Size>(s));
368 }
369 template <typename T, int Size>
bitwiseXorVecScalar(const Vector<T,Size> & v,T s)370 inline Vector<T, Size> bitwiseXorVecScalar(const Vector<T, Size> &v, T s)
371 {
372 return bitwiseXor(v, Vector<T, Size>(s));
373 }
374
375 template <typename T, int Size>
addScalarVec(T s,const Vector<T,Size> & v)376 inline Vector<T, Size> addScalarVec(T s, const Vector<T, Size> &v)
377 {
378 return s + v;
379 }
380 template <typename T, int Size>
subScalarVec(T s,const Vector<T,Size> & v)381 inline Vector<T, Size> subScalarVec(T s, const Vector<T, Size> &v)
382 {
383 return s - v;
384 }
385 template <typename T, int Size>
mulScalarVec(T s,const Vector<T,Size> & v)386 inline Vector<T, Size> mulScalarVec(T s, const Vector<T, Size> &v)
387 {
388 return s * v;
389 }
390 template <typename T, int Size>
divScalarVec(T s,const Vector<T,Size> & v)391 inline Vector<T, Size> divScalarVec(T s, const Vector<T, Size> &v)
392 {
393 return s / v;
394 }
395 template <typename T, int Size>
modScalarVec(T s,const Vector<T,Size> & v)396 inline Vector<T, Size> modScalarVec(T s, const Vector<T, Size> &v)
397 {
398 return mod(Vector<T, Size>(s), v);
399 }
400 template <typename T, int Size>
bitwiseAndScalarVec(T s,const Vector<T,Size> & v)401 inline Vector<T, Size> bitwiseAndScalarVec(T s, const Vector<T, Size> &v)
402 {
403 return bitwiseAnd(Vector<T, Size>(s), v);
404 }
405 template <typename T, int Size>
bitwiseOrScalarVec(T s,const Vector<T,Size> & v)406 inline Vector<T, Size> bitwiseOrScalarVec(T s, const Vector<T, Size> &v)
407 {
408 return bitwiseOr(Vector<T, Size>(s), v);
409 }
410 template <typename T, int Size>
bitwiseXorScalarVec(T s,const Vector<T,Size> & v)411 inline Vector<T, Size> bitwiseXorScalarVec(T s, const Vector<T, Size> &v)
412 {
413 return bitwiseXor(Vector<T, Size>(s), v);
414 }
415
416 // Reference functions for specific sequence operations for the sequence operator tests.
417
418 // Reference for expression "in0, in2 + in1, in1 + in0"
sequenceNoSideEffCase0(const Vec4 & in0,const Vec4 & in1,const Vec4 & in2)419 inline Vec4 sequenceNoSideEffCase0(const Vec4 &in0, const Vec4 &in1, const Vec4 &in2)
420 {
421 DE_UNREF(in2);
422 return in1 + in0;
423 }
424 // Reference for expression "in0, in2 + in1, in1 + in0"
sequenceNoSideEffCase1(float in0,uint32_t in1,float in2)425 inline uint32_t sequenceNoSideEffCase1(float in0, uint32_t in1, float in2)
426 {
427 DE_UNREF(in0);
428 DE_UNREF(in2);
429 return in1 + in1;
430 }
431 // Reference for expression "in0 && in1, in0, ivec2(vec2(in0) + in2)"
sequenceNoSideEffCase2(bool in0,bool in1,const Vec2 & in2)432 inline IVec2 sequenceNoSideEffCase2(bool in0, bool in1, const Vec2 &in2)
433 {
434 DE_UNREF(in1);
435 return IVec2((int)((float)in0 + in2.x()), (int)((float)in0 + in2.y()));
436 }
437 // Reference for expression "in0 + vec4(in1), in2, in1"
sequenceNoSideEffCase3(const Vec4 & in0,const IVec4 & in1,const BVec4 & in2)438 inline IVec4 sequenceNoSideEffCase3(const Vec4 &in0, const IVec4 &in1, const BVec4 &in2)
439 {
440 DE_UNREF(in0);
441 DE_UNREF(in2);
442 return in1;
443 }
444 // Reference for expression "in0++, in1 = in0 + in2, in2 = in1"
sequenceSideEffCase0(const Vec4 & in0,const Vec4 & in1,const Vec4 & in2)445 inline Vec4 sequenceSideEffCase0(const Vec4 &in0, const Vec4 &in1, const Vec4 &in2)
446 {
447 DE_UNREF(in1);
448 return in0 + 1.0f + in2;
449 }
450 // Reference for expression "in1++, in0 = float(in1), in1 = uint(in0 + in2)"
sequenceSideEffCase1(float in0,uint32_t in1,float in2)451 inline uint32_t sequenceSideEffCase1(float in0, uint32_t in1, float in2)
452 {
453 DE_UNREF(in0);
454 return (uint32_t)(float(in1) + 1.0f + in2);
455 }
456 // Reference for expression "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)"
sequenceSideEffCase2(bool in0,bool in1,const Vec2 & in2)457 inline IVec2 sequenceSideEffCase2(bool in0, bool in1, const Vec2 &in2)
458 {
459 DE_UNREF(in1);
460 return (in2 + Vec2(1.0f) + Vec2((float)in0)).asInt();
461 }
462 // Reference for expression "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++"
sequenceSideEffCase3(const Vec4 & in0,const IVec4 & in1,const BVec4 & in2)463 inline IVec4 sequenceSideEffCase3(const Vec4 &in0, const IVec4 &in1, const BVec4 &in2)
464 {
465 return in1 + (in0 + Vec4((float)in2.x(), (float)in2.y(), (float)in2.z(), (float)in2.w())).asInt();
466 }
467
468 // ShaderEvalFunc-type wrappers for the above functions.
evalSequenceNoSideEffCase0(ShaderEvalContext & ctx)469 void evalSequenceNoSideEffCase0(ShaderEvalContext &ctx)
470 {
471 ctx.color = sequenceNoSideEffCase0(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0),
472 ctx.in[2].swizzle(0, 3, 2, 1));
473 }
evalSequenceNoSideEffCase1(ShaderEvalContext & ctx)474 void evalSequenceNoSideEffCase1(ShaderEvalContext &ctx)
475 {
476 ctx.color.x() = (float)sequenceNoSideEffCase1(ctx.in[0].z(), (uint32_t)ctx.in[1].x(), ctx.in[2].y());
477 }
evalSequenceNoSideEffCase2(ShaderEvalContext & ctx)478 void evalSequenceNoSideEffCase2(ShaderEvalContext &ctx)
479 {
480 ctx.color.yz() =
481 sequenceNoSideEffCase2(ctx.in[0].z() > 0.0f, ctx.in[1].x() > 0.0f, ctx.in[2].swizzle(2, 1)).asFloat();
482 }
evalSequenceNoSideEffCase3(ShaderEvalContext & ctx)483 void evalSequenceNoSideEffCase3(ShaderEvalContext &ctx)
484 {
485 ctx.color = sequenceNoSideEffCase3(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0).asInt(),
486 greaterThan(ctx.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f)))
487 .asFloat();
488 }
evalSequenceSideEffCase0(ShaderEvalContext & ctx)489 void evalSequenceSideEffCase0(ShaderEvalContext &ctx)
490 {
491 ctx.color = sequenceSideEffCase0(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0),
492 ctx.in[2].swizzle(0, 3, 2, 1));
493 }
evalSequenceSideEffCase1(ShaderEvalContext & ctx)494 void evalSequenceSideEffCase1(ShaderEvalContext &ctx)
495 {
496 ctx.color.x() = (float)sequenceSideEffCase1(ctx.in[0].z(), (uint32_t)ctx.in[1].x(), ctx.in[2].y());
497 }
evalSequenceSideEffCase2(ShaderEvalContext & ctx)498 void evalSequenceSideEffCase2(ShaderEvalContext &ctx)
499 {
500 ctx.color.yz() =
501 sequenceSideEffCase2(ctx.in[0].z() > 0.0f, ctx.in[1].x() > 0.0f, ctx.in[2].swizzle(2, 1)).asFloat();
502 }
evalSequenceSideEffCase3(ShaderEvalContext & ctx)503 void evalSequenceSideEffCase3(ShaderEvalContext &ctx)
504 {
505 ctx.color = sequenceSideEffCase3(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0).asInt(),
506 greaterThan(ctx.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f)))
507 .asFloat();
508 }
509
stringJoin(const vector<string> & elems,const string & delim)510 static string stringJoin(const vector<string> &elems, const string &delim)
511 {
512 string result;
513 for (int i = 0; i < (int)elems.size(); i++)
514 result += (i > 0 ? delim : "") + elems[i];
515 return result;
516 }
517
stringReplace(string & str,const string & from,const string & to)518 static void stringReplace(string &str, const string &from, const string &to)
519 {
520 size_t start_pos = 0;
521 while ((start_pos = str.find(from, start_pos)) != std::string::npos)
522 {
523 str.replace(start_pos, from.length(), to);
524 start_pos += to.length();
525 }
526 }
527
twoValuedVec4(const string & first,const string & second,const BVec4 & firstMask)528 static string twoValuedVec4(const string &first, const string &second, const BVec4 &firstMask)
529 {
530 vector<string> elems(4);
531 for (int i = 0; i < 4; i++)
532 elems[i] = firstMask[i] ? first : second;
533
534 return "vec4(" + stringJoin(elems, ", ") + ")";
535 }
536
537 enum
538 {
539 MAX_INPUTS = 3
540 };
541
542 enum PrecisionMask
543 {
544 PRECMASK_NA = 0, //!< Precision not applicable (booleans)
545 PRECMASK_LOWP = (1 << PRECISION_LOWP),
546 PRECMASK_MEDIUMP = (1 << PRECISION_MEDIUMP),
547 PRECMASK_HIGHP = (1 << PRECISION_HIGHP),
548
549 PRECMASK_LOWP_MEDIUMP = PRECMASK_LOWP | PRECMASK_MEDIUMP,
550 PRECMASK_MEDIUMP_HIGHP = PRECMASK_MEDIUMP | PRECMASK_HIGHP,
551 PRECMASK_ALL = PRECMASK_LOWP | PRECMASK_MEDIUMP | PRECMASK_HIGHP
552 };
553
554 enum ValueType
555 {
556 VALUE_NONE = 0,
557 VALUE_FLOAT = (1 << 0), // float scalar
558 VALUE_FLOAT_VEC = (1 << 1), // float vector
559 VALUE_FLOAT_GENTYPE = (1 << 2), // float scalar/vector
560 VALUE_VEC3 = (1 << 3), // vec3 only
561 VALUE_MATRIX = (1 << 4), // matrix
562 VALUE_BOOL = (1 << 5), // boolean scalar
563 VALUE_BOOL_VEC = (1 << 6), // boolean vector
564 VALUE_BOOL_GENTYPE = (1 << 7), // boolean scalar/vector
565 VALUE_INT = (1 << 8), // int scalar
566 VALUE_INT_VEC = (1 << 9), // int vector
567 VALUE_INT_GENTYPE = (1 << 10), // int scalar/vector
568 VALUE_UINT = (1 << 11), // uint scalar
569 VALUE_UINT_VEC = (1 << 12), // uint vector
570 VALUE_UINT_GENTYPE = (1 << 13), // uint scalar/vector
571
572 // Shorthands.
573 F = VALUE_FLOAT,
574 FV = VALUE_FLOAT_VEC,
575 GT = VALUE_FLOAT_GENTYPE,
576 V3 = VALUE_VEC3,
577 M = VALUE_MATRIX,
578 B = VALUE_BOOL,
579 BV = VALUE_BOOL_VEC,
580 BGT = VALUE_BOOL_GENTYPE,
581 I = VALUE_INT,
582 IV = VALUE_INT_VEC,
583 IGT = VALUE_INT_GENTYPE,
584 U = VALUE_UINT,
585 UV = VALUE_UINT_VEC,
586 UGT = VALUE_UINT_GENTYPE
587 };
588
isScalarType(ValueType type)589 static inline bool isScalarType(ValueType type)
590 {
591 return type == VALUE_FLOAT || type == VALUE_BOOL || type == VALUE_INT || type == VALUE_UINT;
592 }
593
isFloatType(ValueType type)594 static inline bool isFloatType(ValueType type)
595 {
596 return (type & (VALUE_FLOAT | VALUE_FLOAT_VEC | VALUE_FLOAT_GENTYPE)) != 0;
597 }
598
isIntType(ValueType type)599 static inline bool isIntType(ValueType type)
600 {
601 return (type & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0;
602 }
603
isUintType(ValueType type)604 static inline bool isUintType(ValueType type)
605 {
606 return (type & (VALUE_UINT | VALUE_UINT_VEC | VALUE_UINT_GENTYPE)) != 0;
607 }
608
isBoolType(ValueType type)609 static inline bool isBoolType(ValueType type)
610 {
611 return (type & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0;
612 }
613
getGLSLUintBits(const glw::Functions & gl,ShaderType shaderType,Precision uintPrecision)614 static inline int getGLSLUintBits(const glw::Functions &gl, ShaderType shaderType, Precision uintPrecision)
615 {
616 uint32_t intPrecisionGL;
617 uint32_t shaderTypeGL;
618
619 switch (uintPrecision)
620 {
621 case PRECISION_LOWP:
622 intPrecisionGL = GL_LOW_INT;
623 break;
624 case PRECISION_MEDIUMP:
625 intPrecisionGL = GL_MEDIUM_INT;
626 break;
627 case PRECISION_HIGHP:
628 intPrecisionGL = GL_HIGH_INT;
629 break;
630 default:
631 DE_ASSERT(false);
632 intPrecisionGL = 0;
633 }
634
635 switch (shaderType)
636 {
637 case SHADERTYPE_VERTEX:
638 shaderTypeGL = GL_VERTEX_SHADER;
639 break;
640 case SHADERTYPE_FRAGMENT:
641 shaderTypeGL = GL_FRAGMENT_SHADER;
642 break;
643 default:
644 DE_ASSERT(false);
645 shaderTypeGL = 0;
646 }
647
648 glw::GLint range[2] = {-1, -1};
649 glw::GLint precision = -1;
650
651 gl.getShaderPrecisionFormat(shaderTypeGL, intPrecisionGL, &range[0], &precision);
652 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderPrecisionFormat failed");
653
654 TCU_CHECK(de::inBounds(range[0], 8, 32));
655
656 const int numBitsInType = range[0] + 1;
657 return numBitsInType;
658 }
659
getGLSLUintMaxAsFloat(const glw::Functions & gl,ShaderType shaderType,Precision uintPrecision)660 static inline float getGLSLUintMaxAsFloat(const glw::Functions &gl, ShaderType shaderType, Precision uintPrecision)
661 {
662 const int numBitsInType = getGLSLUintBits(gl, shaderType, uintPrecision);
663 const float maxAsFloat = static_cast<float>((1ull << numBitsInType) - 1);
664 const float maxRepresentableAsFloat = floorf(nextafterf(maxAsFloat, 0));
665
666 // Not accurate for integers wider than 24 bits.
667 return numBitsInType > 24 ? maxRepresentableAsFloat : maxAsFloat;
668 }
669
670 // Float scalar that can be either constant or a symbol that can be evaluated later.
671 class FloatScalar
672 {
673 public:
674 enum Symbol
675 {
676 SYMBOL_LOWP_UINT_MAX = 0,
677 SYMBOL_MEDIUMP_UINT_MAX,
678
679 SYMBOL_LOWP_UINT_MAX_RECIPROCAL,
680 SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL,
681
682 SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX,
683 SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX,
684
685 SYMBOL_LAST
686 };
687
FloatScalar(float c)688 FloatScalar(float c) : m_isConstant(true), m_value(c)
689 {
690 }
FloatScalar(Symbol s)691 FloatScalar(Symbol s) : m_isConstant(false), m_value(s)
692 {
693 }
694
getValue(const glw::Functions & gl,ShaderType shaderType) const695 float getValue(const glw::Functions &gl, ShaderType shaderType) const
696 {
697 if (m_isConstant)
698 return m_value.constant;
699 else
700 {
701 switch (m_value.symbol)
702 {
703 case SYMBOL_LOWP_UINT_MAX:
704 return getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_LOWP);
705 case SYMBOL_MEDIUMP_UINT_MAX:
706 return getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_MEDIUMP);
707
708 case SYMBOL_LOWP_UINT_MAX_RECIPROCAL:
709 return 1.0f / getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_LOWP);
710 case SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL:
711 return 1.0f / getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_MEDIUMP);
712
713 case SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX:
714 return 1.0f - (float)std::numeric_limits<uint32_t>::max() /
715 getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_LOWP);
716 case SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX:
717 return 1.0f - (float)std::numeric_limits<uint32_t>::max() /
718 getGLSLUintMaxAsFloat(gl, shaderType, PRECISION_MEDIUMP);
719
720 default:
721 DE_ASSERT(false);
722 return 0.0f;
723 }
724 }
725 }
726
getValueMask(const glw::Functions & gl,ShaderType shaderType) const727 uint32_t getValueMask(const glw::Functions &gl, ShaderType shaderType) const
728 {
729 if (m_isConstant)
730 return 0;
731
732 int bits = 0;
733 switch (m_value.symbol)
734 {
735 case SYMBOL_LOWP_UINT_MAX_RECIPROCAL:
736 case SYMBOL_LOWP_UINT_MAX:
737 bits = getGLSLUintBits(gl, shaderType, PRECISION_LOWP);
738 break;
739
740 case SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL:
741 case SYMBOL_MEDIUMP_UINT_MAX:
742 bits = getGLSLUintBits(gl, shaderType, PRECISION_MEDIUMP);
743 break;
744
745 case SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX:
746 case SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX:
747 return 0;
748
749 default:
750 DE_ASSERT(false);
751 return 0;
752 }
753
754 return bits == 32 ? 0 : (1u << bits) - 1;
755 }
756
757 private:
758 bool m_isConstant;
759
760 union ConstantOrSymbol
761 {
762 float constant;
763 Symbol symbol;
764
ConstantOrSymbol(float c)765 ConstantOrSymbol(float c) : constant(c)
766 {
767 }
ConstantOrSymbol(Symbol s)768 ConstantOrSymbol(Symbol s) : symbol(s)
769 {
770 }
771 } m_value;
772 };
773
774 struct Value
775 {
Valuedeqp::gles3::Functional::Value776 Value(ValueType valueType_, const FloatScalar &rangeMin_, const FloatScalar &rangeMax_)
777 : valueType(valueType_)
778 , rangeMin(rangeMin_)
779 , rangeMax(rangeMax_)
780 {
781 }
782
783 ValueType valueType;
784 FloatScalar rangeMin;
785 FloatScalar rangeMax;
786 };
787
788 enum OperationType
789 {
790 FUNCTION = 0,
791 OPERATOR,
792 SIDE_EFFECT_OPERATOR // Test the side-effect (as opposed to the result) of a side-effect operator.
793 };
794
795 struct BuiltinFuncInfo
796 {
BuiltinFuncInfodeqp::gles3::Functional::BuiltinFuncInfo797 BuiltinFuncInfo(const char *caseName_, const char *shaderFuncName_, ValueType outValue_, Value input0_,
798 Value input1_, Value input2_, const FloatScalar &resultScale_, const FloatScalar &resultBias_,
799 uint32_t precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_,
800 ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_, OperationType type_ = FUNCTION,
801 bool isUnaryPrefix_ = true)
802 : caseName(caseName_)
803 , shaderFuncName(shaderFuncName_)
804 , outValue(outValue_)
805 , input0(input0_)
806 , input1(input1_)
807 , input2(input2_)
808 , resultScale(resultScale_)
809 , resultBias(resultBias_)
810 , referenceScale(resultScale_)
811 , referenceBias(resultBias_)
812 , precisionMask(precisionMask_)
813 , evalFuncScalar(evalFuncScalar_)
814 , evalFuncVec2(evalFuncVec2_)
815 , evalFuncVec3(evalFuncVec3_)
816 , evalFuncVec4(evalFuncVec4_)
817 , type(type_)
818 , isUnaryPrefix(isUnaryPrefix_)
819 {
820 }
821
BuiltinFuncInfodeqp::gles3::Functional::BuiltinFuncInfo822 BuiltinFuncInfo(const char *caseName_, const char *shaderFuncName_, ValueType outValue_, Value input0_,
823 Value input1_, Value input2_, const FloatScalar &resultScale_, const FloatScalar &resultBias_,
824 const FloatScalar &referenceScale_, const FloatScalar &referenceBias_, uint32_t precisionMask_,
825 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
826 ShaderEvalFunc evalFuncVec4_, OperationType type_ = FUNCTION, bool isUnaryPrefix_ = true)
827 : caseName(caseName_)
828 , shaderFuncName(shaderFuncName_)
829 , outValue(outValue_)
830 , input0(input0_)
831 , input1(input1_)
832 , input2(input2_)
833 , resultScale(resultScale_)
834 , resultBias(resultBias_)
835 , referenceScale(referenceScale_)
836 , referenceBias(referenceBias_)
837 , precisionMask(precisionMask_)
838 , evalFuncScalar(evalFuncScalar_)
839 , evalFuncVec2(evalFuncVec2_)
840 , evalFuncVec3(evalFuncVec3_)
841 , evalFuncVec4(evalFuncVec4_)
842 , type(type_)
843 , isUnaryPrefix(isUnaryPrefix_)
844 {
845 }
846
847 const char *caseName; //!< Name of case.
848 const char *shaderFuncName; //!< Name in shading language.
849 ValueType outValue;
850 Value input0;
851 Value input1;
852 Value input2;
853 FloatScalar resultScale;
854 FloatScalar resultBias;
855 FloatScalar referenceScale;
856 FloatScalar referenceBias;
857 uint32_t precisionMask;
858 ShaderEvalFunc evalFuncScalar;
859 ShaderEvalFunc evalFuncVec2;
860 ShaderEvalFunc evalFuncVec3;
861 ShaderEvalFunc evalFuncVec4;
862 OperationType type;
863 bool isUnaryPrefix; //!< Whether a unary operator is a prefix operator; redundant unless unary.
864 };
865
BuiltinOperInfo(const char * caseName_,const char * shaderFuncName_,ValueType outValue_,Value input0_,Value input1_,Value input2_,const FloatScalar & resultScale_,const FloatScalar & resultBias_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)866 static inline BuiltinFuncInfo BuiltinOperInfo(const char *caseName_, const char *shaderFuncName_, ValueType outValue_,
867 Value input0_, Value input1_, Value input2_,
868 const FloatScalar &resultScale_, const FloatScalar &resultBias_,
869 uint32_t precisionMask_, ShaderEvalFunc evalFuncScalar_,
870 ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
871 ShaderEvalFunc evalFuncVec4_)
872 {
873 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
874 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
875 evalFuncVec4_, OPERATOR);
876 }
877
BuiltinOperInfoSeparateRefScaleBias(const char * caseName_,const char * shaderFuncName_,ValueType outValue_,Value input0_,Value input1_,Value input2_,const FloatScalar & resultScale_,const FloatScalar & resultBias_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_,const FloatScalar & referenceScale_,const FloatScalar & referenceBias_)878 static inline BuiltinFuncInfo BuiltinOperInfoSeparateRefScaleBias(
879 const char *caseName_, const char *shaderFuncName_, ValueType outValue_, Value input0_, Value input1_,
880 Value input2_, const FloatScalar &resultScale_, const FloatScalar &resultBias_, uint32_t precisionMask_,
881 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
882 ShaderEvalFunc evalFuncVec4_, const FloatScalar &referenceScale_, const FloatScalar &referenceBias_)
883 {
884 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
885 referenceScale_, referenceBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_,
886 evalFuncVec3_, evalFuncVec4_, OPERATOR);
887 }
888
889 // 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_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)890 static inline BuiltinFuncInfo BuiltinPostOperInfo(const char *caseName_, const char *shaderFuncName_,
891 ValueType outValue_, Value input0_, Value input1_, Value input2_,
892 const FloatScalar &resultScale_, const FloatScalar &resultBias_,
893 uint32_t precisionMask_, ShaderEvalFunc evalFuncScalar_,
894 ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
895 ShaderEvalFunc evalFuncVec4_)
896 {
897 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
898 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
899 evalFuncVec4_, OPERATOR, false);
900 }
901
BuiltinSideEffOperInfo(const char * caseName_,const char * shaderFuncName_,ValueType outValue_,Value input0_,Value input1_,Value input2_,const FloatScalar & resultScale_,const FloatScalar & resultBias_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)902 static inline BuiltinFuncInfo BuiltinSideEffOperInfo(const char *caseName_, const char *shaderFuncName_,
903 ValueType outValue_, Value input0_, Value input1_, Value input2_,
904 const FloatScalar &resultScale_, const FloatScalar &resultBias_,
905 uint32_t precisionMask_, ShaderEvalFunc evalFuncScalar_,
906 ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
907 ShaderEvalFunc evalFuncVec4_)
908 {
909 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
910 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
911 evalFuncVec4_, SIDE_EFFECT_OPERATOR);
912 }
913
914 // 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_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)915 static inline BuiltinFuncInfo BuiltinPostSideEffOperInfo(const char *caseName_, const char *shaderFuncName_,
916 ValueType outValue_, Value input0_, Value input1_,
917 Value input2_, const FloatScalar &resultScale_,
918 const FloatScalar &resultBias_, uint32_t precisionMask_,
919 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_,
920 ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_)
921 {
922 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
923 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
924 evalFuncVec4_, SIDE_EFFECT_OPERATOR, false);
925 }
926
927 // BuiltinFuncGroup
928
929 struct BuiltinFuncGroup
930 {
BuiltinFuncGroupdeqp::gles3::Functional::BuiltinFuncGroup931 BuiltinFuncGroup(const char *name_, const char *description_) : name(name_), description(description_)
932 {
933 }
operator <<deqp::gles3::Functional::BuiltinFuncGroup934 BuiltinFuncGroup &operator<<(const BuiltinFuncInfo &info)
935 {
936 funcInfos.push_back(info);
937 return *this;
938 }
939
940 const char *name;
941 const char *description;
942 std::vector<BuiltinFuncInfo> funcInfos;
943 };
944
945 static const char *s_inSwizzles[MAX_INPUTS][4] = {{"z", "wy", "zxy", "yzwx"},
946 {"x", "yx", "yzx", "wzyx"},
947 {"y", "zy", "wyz", "xwzy"}};
948
949 static const char *s_outSwizzles[] = {"x", "yz", "xyz", "xyzw"};
950
951 static const BVec4 s_outSwizzleChannelMasks[] = {BVec4(true, false, false, false), BVec4(false, true, true, false),
952 BVec4(true, true, true, false), BVec4(true, true, true, true)};
953
954 // OperatorShaderEvaluator
955
956 class OperatorShaderEvaluator : public ShaderEvaluator
957 {
958 public:
OperatorShaderEvaluator(const glw::Functions & gl,ShaderType shaderType,ShaderEvalFunc evalFunc,const FloatScalar & scale,const FloatScalar & bias,int resultScalarSize)959 OperatorShaderEvaluator(const glw::Functions &gl, ShaderType shaderType, ShaderEvalFunc evalFunc,
960 const FloatScalar &scale, const FloatScalar &bias, int resultScalarSize)
961 : m_gl(gl)
962 , m_shaderType(shaderType)
963 , m_evalFunc(evalFunc)
964 , m_scale(scale)
965 , m_bias(bias)
966 , m_resultScalarSize(resultScalarSize)
967 , m_areScaleAndBiasEvaluated(false)
968 , m_evaluatedScale(-1.0f)
969 , m_evaluatedBias(-1.0f)
970 {
971 DE_ASSERT(de::inRange(resultScalarSize, 1, 4));
972 }
973
~OperatorShaderEvaluator(void)974 virtual ~OperatorShaderEvaluator(void)
975 {
976 }
977
evaluate(ShaderEvalContext & ctx)978 virtual void evaluate(ShaderEvalContext &ctx)
979 {
980 m_evalFunc(ctx);
981
982 if (!m_areScaleAndBiasEvaluated)
983 {
984 m_evaluatedScale = m_scale.getValue(m_gl, m_shaderType);
985 m_evaluatedBias = m_bias.getValue(m_gl, m_shaderType);
986 m_areScaleAndBiasEvaluated = true;
987 }
988
989 for (int i = 0; i < 4; i++)
990 if (s_outSwizzleChannelMasks[m_resultScalarSize - 1][i])
991 ctx.color[i] = ctx.color[i] * m_evaluatedScale + m_evaluatedBias;
992 }
993
994 private:
995 const glw::Functions &m_gl;
996 ShaderType m_shaderType;
997 ShaderEvalFunc m_evalFunc;
998 FloatScalar m_scale;
999 FloatScalar m_bias;
1000 int m_resultScalarSize;
1001
1002 bool m_areScaleAndBiasEvaluated;
1003 float m_evaluatedScale;
1004 float m_evaluatedBias;
1005 };
1006
1007 // Concrete value.
1008
1009 struct ShaderValue
1010 {
ShaderValuedeqp::gles3::Functional::ShaderValue1011 ShaderValue(DataType type_, const FloatScalar &rangeMin_, const FloatScalar &rangeMax_)
1012 : type(type_)
1013 , rangeMin(rangeMin_)
1014 , rangeMax(rangeMax_)
1015 {
1016 }
1017
ShaderValuedeqp::gles3::Functional::ShaderValue1018 ShaderValue(void) : type(TYPE_LAST), rangeMin(0.0f), rangeMax(0.0f)
1019 {
1020 }
1021
1022 DataType type;
1023 FloatScalar rangeMin;
1024 FloatScalar rangeMax;
1025 };
1026
1027 struct ShaderDataSpec
1028 {
ShaderDataSpecdeqp::gles3::Functional::ShaderDataSpec1029 ShaderDataSpec(void)
1030 : resultScale(1.0f)
1031 , resultBias(0.0f)
1032 , referenceScale(1.0f)
1033 , referenceBias(0.0f)
1034 , precision(PRECISION_LAST)
1035 , output(TYPE_LAST)
1036 , numInputs(0)
1037 {
1038 }
1039
1040 FloatScalar resultScale;
1041 FloatScalar resultBias;
1042 FloatScalar referenceScale;
1043 FloatScalar referenceBias;
1044 Precision precision;
1045 DataType output;
1046 int numInputs;
1047 ShaderValue inputs[MAX_INPUTS];
1048 };
1049
1050 // ShaderOperatorCase
1051
1052 class ShaderOperatorCase : public ShaderRenderCase
1053 {
1054 public:
1055 ShaderOperatorCase(Context &context, const char *caseName, const char *description, bool isVertexCase,
1056 ShaderEvalFunc evalFunc, const string &shaderOp, const ShaderDataSpec &spec);
1057 virtual ~ShaderOperatorCase(void);
1058
1059 protected:
1060 void setupShaderData(void);
1061
1062 private:
1063 ShaderOperatorCase(const ShaderOperatorCase &); // not allowed!
1064 ShaderOperatorCase &operator=(const ShaderOperatorCase &); // not allowed!
1065
1066 ShaderDataSpec m_spec;
1067 string m_shaderOp;
1068 OperatorShaderEvaluator m_evaluator;
1069 };
1070
ShaderOperatorCase(Context & context,const char * caseName,const char * description,bool isVertexCase,ShaderEvalFunc evalFunc,const string & shaderOp,const ShaderDataSpec & spec)1071 ShaderOperatorCase::ShaderOperatorCase(Context &context, const char *caseName, const char *description,
1072 bool isVertexCase, ShaderEvalFunc evalFunc, const string &shaderOp,
1073 const ShaderDataSpec &spec)
1074 : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), caseName,
1075 description, isVertexCase, m_evaluator)
1076 , m_spec(spec)
1077 , m_shaderOp(shaderOp)
1078 , m_evaluator(m_renderCtx.getFunctions(), isVertexCase ? SHADERTYPE_VERTEX : SHADERTYPE_FRAGMENT, evalFunc,
1079 spec.referenceScale, spec.referenceBias, getDataTypeScalarSize(spec.output))
1080 {
1081 }
1082
setupShaderData(void)1083 void ShaderOperatorCase::setupShaderData(void)
1084 {
1085 ShaderType shaderType = m_isVertexCase ? SHADERTYPE_VERTEX : SHADERTYPE_FRAGMENT;
1086 const char *precision = m_spec.precision != PRECISION_LAST ? getPrecisionName(m_spec.precision) : DE_NULL;
1087 const char *inputPrecision[MAX_INPUTS];
1088
1089 ostringstream vtx;
1090 ostringstream frag;
1091 ostringstream &op = m_isVertexCase ? vtx : frag;
1092
1093 vtx << "#version 300 es\n";
1094 frag << "#version 300 es\n";
1095
1096 // Compute precision for inputs.
1097 for (int i = 0; i < m_spec.numInputs; i++)
1098 {
1099 bool isBoolVal = de::inRange<int>(m_spec.inputs[i].type, TYPE_BOOL, TYPE_BOOL_VEC4);
1100 bool isIntVal = de::inRange<int>(m_spec.inputs[i].type, TYPE_INT, TYPE_INT_VEC4);
1101 bool isUintVal = de::inRange<int>(m_spec.inputs[i].type, TYPE_UINT, TYPE_UINT_VEC4);
1102 // \note Mediump interpolators are used for booleans, and highp for integers.
1103 Precision prec = isBoolVal ? PRECISION_MEDIUMP : isIntVal || isUintVal ? PRECISION_HIGHP : m_spec.precision;
1104 inputPrecision[i] = getPrecisionName(prec);
1105 }
1106
1107 // Attributes.
1108 vtx << "in highp vec4 a_position;\n";
1109 for (int i = 0; i < m_spec.numInputs; i++)
1110 vtx << "in " << inputPrecision[i] << " vec4 a_in" << i << ";\n";
1111
1112 // Color output.
1113 frag << "layout(location = 0) out mediump vec4 o_color;\n";
1114
1115 if (m_isVertexCase)
1116 {
1117 vtx << "out mediump vec4 v_color;\n";
1118 frag << "in mediump vec4 v_color;\n";
1119 }
1120 else
1121 {
1122 for (int i = 0; i < m_spec.numInputs; i++)
1123 {
1124 vtx << "out " << inputPrecision[i] << " vec4 v_in" << i << ";\n";
1125 frag << "in " << inputPrecision[i] << " vec4 v_in" << i << ";\n";
1126 }
1127 }
1128
1129 vtx << "\n";
1130 vtx << "void main()\n";
1131 vtx << "{\n";
1132 vtx << " gl_Position = a_position;\n";
1133
1134 frag << "\n";
1135 frag << "void main()\n";
1136 frag << "{\n";
1137
1138 bool isResFloatVec = de::inRange<int>(m_spec.output, TYPE_FLOAT, TYPE_FLOAT_VEC4);
1139 bool isResBoolVec = de::inRange<int>(m_spec.output, TYPE_BOOL, TYPE_BOOL_VEC4);
1140 bool hasReference = !isResFloatVec && !isResBoolVec &&
1141 (m_spec.precision == PRECISION_LOWP || m_spec.precision == PRECISION_MEDIUMP);
1142 string refShaderOp = m_shaderOp;
1143
1144 // Expression inputs.
1145 string prefix = m_isVertexCase ? "a_" : "v_";
1146 for (int i = 0; i < m_spec.numInputs; i++)
1147 {
1148 DataType inType = m_spec.inputs[i].type;
1149 int inSize = getDataTypeScalarSize(inType);
1150 bool isBool = de::inRange<int>(inType, TYPE_BOOL, TYPE_BOOL_VEC4);
1151 bool isInt = de::inRange<int>(inType, TYPE_INT, TYPE_INT_VEC4);
1152 bool isUint = de::inRange<int>(inType, TYPE_UINT, TYPE_UINT_VEC4);
1153 const char *typeName = getDataTypeName(inType);
1154 const char *swizzle = s_inSwizzles[i][inSize - 1];
1155 bool hasReferenceIn = hasReference && !isBool;
1156
1157 // For int/uint types, generate:
1158 //
1159 // highp type highp_inN = ...;
1160 // precision type inN = highp_inN;
1161 //
1162 // inN_high will be used later for reference checking.
1163 //
1164 // For other types, generate:
1165 //
1166 // precision type inN = ...;
1167 //
1168 op << "\t";
1169 if (precision && !isBool)
1170 {
1171 if (hasReferenceIn)
1172 op << "highp ";
1173 else
1174 op << precision << " ";
1175 }
1176
1177 op << typeName << " ";
1178 if (hasReferenceIn)
1179 op << "highp_";
1180 op << "in" << i << " = ";
1181
1182 if (isBool)
1183 {
1184 if (inSize == 1)
1185 op << "(";
1186 else
1187 op << "greaterThan(";
1188 }
1189 else if (isInt || isUint)
1190 op << typeName << "(";
1191
1192 op << prefix << "in" << i << "." << swizzle;
1193
1194 if (isBool)
1195 {
1196 if (inSize == 1)
1197 op << " > 0.0)";
1198 else
1199 op << ", vec" << inSize << "(0.0))";
1200 }
1201 else if (isInt || isUint)
1202 op << ")";
1203
1204 op << ";\n";
1205
1206 if (hasReferenceIn)
1207 {
1208 op << "\t" << precision << " " << typeName << " in" << i << " = highp_in" << i << ";\n";
1209
1210 string inputName = "in" + string(1, static_cast<char>('0' + i));
1211 stringReplace(refShaderOp, inputName, "highp_" + inputName);
1212 }
1213 }
1214
1215 // Result variable.
1216 {
1217 const char *outTypeName = getDataTypeName(m_spec.output);
1218 bool isBoolOut = de::inRange<int>(m_spec.output, TYPE_BOOL, TYPE_BOOL_VEC4);
1219
1220 op << "\t";
1221 if (precision && !isBoolOut)
1222 op << precision << " ";
1223 op << outTypeName << " res = " << outTypeName << "(0.0);\n";
1224
1225 if (hasReference)
1226 {
1227 op << "\thighp " << outTypeName << " ref = " << outTypeName << "(0.0);\n";
1228 }
1229
1230 op << "\n";
1231 }
1232
1233 // Expression.
1234 op << "\t" << m_shaderOp << "\n";
1235 if (hasReference)
1236 {
1237 stringReplace(refShaderOp, "res", "ref");
1238 op << "\t" << refShaderOp << "\n";
1239 }
1240 op << "\n";
1241
1242 // Implementations may use more bits than advertised. Assume an implementation advertising 16
1243 // bits for mediump, but actually using 24 bits for a particular operation. We have:
1244 //
1245 // highp ref = expr;
1246 // mediump res = expr;
1247 //
1248 // We expect res&0xFFFF to be correct, because that ensures that _at least_ 16 bits were
1249 // provided. However, we also need to make sure that if there is anything in the upper 16 bits
1250 // of res, that those bits match with ref. In short, we expect to see the following bits
1251 // (assume the advertised number of bits is N, and the actual calculation is done in M bits):
1252 //
1253 // ref = a31 ... aM aM-1 ... aN aN-1 ... a0
1254 // res = 0 ... 0 bM-1 ... bN bN-1 ... b0
1255 //
1256 // The test verifies that bN-1 ... b0 is correct based on the shader output. We additionally
1257 // want to make sure that:
1258 //
1259 // - bM-1 ... bN is identical to aM-1 ... aN
1260 // - bits above bM-1 are zero.
1261 //
1262 // This is done as follows:
1263 //
1264 // diff = res ^ ref --> should produce a31 ... aM 0 ... 0
1265 // diff == 0: accept res
1266 // diff != 0:
1267 // lsb = log2((~diff + 1u) & diff) --> log2(0 .. 0 1 0 ...0)
1268 // == findLSB(diff)
1269 //
1270 // outOfRangeMask = 0xFFFFFFFF << lsb --> 1 ... 1 0 ... 0
1271 //
1272 // (res & outOfRangeMask) == 0: accept res
1273 //
1274 // Note that (diff & ~outOfRangeMask) == 0 necessarily holds, because outOfRangeMask has 1s
1275 // starting from the first bit that differs between res and ref, which means that res and ref
1276 // are identical in those bits.
1277 int outScalarSize = getDataTypeScalarSize(m_spec.output);
1278 string floatType = "";
1279 if (!isResFloatVec)
1280 {
1281 if (outScalarSize == 1)
1282 floatType = "float";
1283 else
1284 floatType = "vec" + string(1, static_cast<char>('0' + outScalarSize));
1285 }
1286
1287 if (hasReference)
1288 {
1289 bool isInt = de::inRange<int>(m_spec.output, TYPE_INT, TYPE_INT_VEC4);
1290 const char *outTypeName = getDataTypeName(m_spec.output);
1291 const char *outBasicTypeName = getDataTypeName(isInt ? TYPE_INT : TYPE_UINT);
1292 uint32_t resultMask = m_spec.resultScale.getValueMask(m_renderCtx.getFunctions(), shaderType);
1293
1294 op << "\thighp " << outTypeName << " diff = res ^ ref;\n";
1295 op << "\tdiff = (~diff + " << outTypeName << "(1)) & diff;\n";
1296 op << "\thighp " << outTypeName << " lsb = " << outTypeName << "(32);\n";
1297 op << "\thighp " << outTypeName << " outOfRangeMask = " << outTypeName << "(0);\n";
1298 if (outScalarSize == 1)
1299 {
1300 op << "\tif (diff != " << outTypeName << "(0))\n\t{\n";
1301 op << "\t\tlsb = " << outTypeName << "(log2(" << floatType << "(diff)));\n";
1302 op << "\t\toutOfRangeMask = " << outTypeName << "(0xFFFFFFFF) << lsb;\n";
1303 op << "\t}\n";
1304 }
1305 else
1306 {
1307 op << "\tbvec" << outScalarSize << " isDiffZero = equal(diff, " << outTypeName << "(0));\n";
1308 op << "\thighp " << outTypeName << " lsbUnsantized = " << outTypeName << "(log2(vec" << outScalarSize
1309 << "((~diff + " << outTypeName << "(1)) & diff)));\n";
1310 for (int channel = 0; channel < outScalarSize; ++channel)
1311 {
1312 op << "\tif (!isDiffZero[" << channel << "])\n\t{\n";
1313 op << "\t\tlsb[" << channel << "] = lsbUnsantized[" << channel << "];\n";
1314 op << "\t\toutOfRangeMask[" << channel << "] = " << outBasicTypeName << "(0xFFFFFFFF) << lsb["
1315 << channel << "];\n";
1316 op << "\t}\n";
1317 }
1318 }
1319 op << "\thighp " << outTypeName << " outOfRangeRes = res & outOfRangeMask;\n";
1320 op << "\tif (outOfRangeRes != " << outTypeName << "(0)) res = " << outTypeName << "(0);\n";
1321
1322 if (resultMask != 0)
1323 op << "\tres &= " << outTypeName << "(" << resultMask << ");\n";
1324
1325 op << "\n";
1326 }
1327
1328 // Convert to color.
1329 op << "\thighp vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n";
1330 op << "\tcolor." << s_outSwizzles[outScalarSize - 1] << " = " << floatType << "(res);\n";
1331
1332 // Scale & bias.
1333 float resultScale = m_spec.resultScale.getValue(m_renderCtx.getFunctions(), shaderType);
1334 float resultBias = m_spec.resultBias.getValue(m_renderCtx.getFunctions(), shaderType);
1335 if ((resultScale != 1.0f) || (resultBias != 0.0f))
1336 {
1337 op << "\tcolor = color";
1338 if (resultScale != 1.0f)
1339 op << " * " << twoValuedVec4(de::toString(resultScale), "1.0", s_outSwizzleChannelMasks[outScalarSize - 1]);
1340 if (resultBias != 0.0f)
1341 op << " + "
1342 << twoValuedVec4(de::floatToString(resultBias, 2), "0.0", s_outSwizzleChannelMasks[outScalarSize - 1]);
1343 op << ";\n";
1344 }
1345
1346 // ..
1347 if (m_isVertexCase)
1348 {
1349 vtx << " v_color = color;\n";
1350 frag << " o_color = v_color;\n";
1351 }
1352 else
1353 {
1354 for (int i = 0; i < m_spec.numInputs; i++)
1355 vtx << " v_in" << i << " = a_in" << i << ";\n";
1356 frag << " o_color = color;\n";
1357 }
1358
1359 vtx << "}\n";
1360 frag << "}\n";
1361
1362 m_vertShaderSource = vtx.str();
1363 m_fragShaderSource = frag.str();
1364
1365 // Setup the user attributes.
1366 m_userAttribTransforms.resize(m_spec.numInputs);
1367 for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
1368 {
1369 const ShaderValue &v = m_spec.inputs[inputNdx];
1370 DE_ASSERT(v.type != TYPE_LAST);
1371
1372 float rangeMin = v.rangeMin.getValue(m_renderCtx.getFunctions(), shaderType);
1373 float rangeMax = v.rangeMax.getValue(m_renderCtx.getFunctions(), shaderType);
1374 float scale = rangeMax - rangeMin;
1375 float minBias = rangeMin;
1376 float maxBias = rangeMax;
1377 Mat4 attribMatrix;
1378
1379 for (int rowNdx = 0; rowNdx < 4; rowNdx++)
1380 {
1381 Vec4 row;
1382
1383 switch ((rowNdx + inputNdx) % 4)
1384 {
1385 case 0:
1386 row = Vec4(scale, 0.0f, 0.0f, minBias);
1387 break;
1388 case 1:
1389 row = Vec4(0.0f, scale, 0.0f, minBias);
1390 break;
1391 case 2:
1392 row = Vec4(-scale, 0.0f, 0.0f, maxBias);
1393 break;
1394 case 3:
1395 row = Vec4(0.0f, -scale, 0.0f, maxBias);
1396 break;
1397 default:
1398 DE_ASSERT(false);
1399 }
1400
1401 attribMatrix.setRow(rowNdx, row);
1402 }
1403
1404 m_userAttribTransforms[inputNdx] = attribMatrix;
1405 }
1406 }
1407
~ShaderOperatorCase(void)1408 ShaderOperatorCase::~ShaderOperatorCase(void)
1409 {
1410 }
1411
1412 // ShaderOperatorTests.
1413
ShaderOperatorTests(Context & context)1414 ShaderOperatorTests::ShaderOperatorTests(Context &context) : TestCaseGroup(context, "operator", "Operator tests.")
1415 {
1416 }
1417
~ShaderOperatorTests(void)1418 ShaderOperatorTests::~ShaderOperatorTests(void)
1419 {
1420 }
1421
1422 // Vector math functions.
1423 template <typename T>
nop(T f)1424 inline T nop(T f)
1425 {
1426 return f;
1427 }
1428
1429 template <typename T, int Size>
nop(const Vector<T,Size> & v)1430 Vector<T, Size> nop(const Vector<T, Size> &v)
1431 {
1432 return v;
1433 }
1434
1435 #define DECLARE_UNARY_GENTYPE_FUNCS(FUNC_NAME) \
1436 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1437 { \
1438 c.color.x() = FUNC_NAME(c.in[0].swizzle(2)).x(); \
1439 } \
1440 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1441 { \
1442 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1)); \
1443 } \
1444 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1445 { \
1446 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1)); \
1447 } \
1448 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1449 { \
1450 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); \
1451 }
1452
1453 #define DECLARE_BINARY_GENTYPE_FUNCS(FUNC_NAME) \
1454 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1455 { \
1456 c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0)).x(); \
1457 } \
1458 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1459 { \
1460 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); \
1461 } \
1462 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1463 { \
1464 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); \
1465 } \
1466 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1467 { \
1468 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); \
1469 }
1470
1471 #define DECLARE_TERNARY_GENTYPE_FUNCS(FUNC_NAME) \
1472 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1473 { \
1474 c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0), c.in[2].swizzle(1)).x(); \
1475 } \
1476 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1477 { \
1478 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0), c.in[2].swizzle(2, 1)); \
1479 } \
1480 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1481 { \
1482 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)); \
1483 } \
1484 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1485 { \
1486 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)); \
1487 }
1488
1489 #define DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME) \
1490 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1491 { \
1492 c.color.x() = FUNC_NAME(c.in[0].swizzle(2)); \
1493 } \
1494 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1495 { \
1496 c.color.x() = FUNC_NAME(c.in[0].swizzle(3, 1)); \
1497 } \
1498 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1499 { \
1500 c.color.x() = FUNC_NAME(c.in[0].swizzle(2, 0, 1)); \
1501 } \
1502 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1503 { \
1504 c.color.x() = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); \
1505 }
1506
1507 #define DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME) \
1508 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1509 { \
1510 c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0)); \
1511 } \
1512 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1513 { \
1514 c.color.x() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); \
1515 } \
1516 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1517 { \
1518 c.color.x() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); \
1519 } \
1520 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1521 { \
1522 c.color.x() = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); \
1523 }
1524
1525 #define DECLARE_BINARY_BOOL_FUNCS(FUNC_NAME) \
1526 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1527 { \
1528 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); \
1529 }
1530
1531 #define DECLARE_UNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME) \
1532 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1533 { \
1534 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f); \
1535 } \
1536 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
1537 { \
1538 c.color.yz() = FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); \
1539 } \
1540 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
1541 { \
1542 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); \
1543 } \
1544 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
1545 { \
1546 c.color = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f))).asFloat(); \
1547 }
1548
1549 #define DECLARE_TERNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME) \
1550 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1551 { \
1552 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f, c.in[2].y() > 0.0f); \
1553 } \
1554 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
1555 { \
1556 c.color.yz() = \
1557 FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)), greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f)), \
1558 greaterThan(c.in[2].swizzle(2, 1), Vec2(0.0f))) \
1559 .asFloat(); \
1560 } \
1561 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
1562 { \
1563 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)), \
1564 greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f)), \
1565 greaterThan(c.in[2].swizzle(3, 1, 2), Vec3(0.0f))) \
1566 .asFloat(); \
1567 } \
1568 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
1569 { \
1570 c.color = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), \
1571 greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f)), \
1572 greaterThan(c.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f))) \
1573 .asFloat(); \
1574 }
1575
1576 #define DECLARE_UNARY_INT_GENTYPE_FUNCS(FUNC_NAME) \
1577 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1578 { \
1579 c.color.x() = (float)FUNC_NAME((int)c.in[0].z()); \
1580 } \
1581 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1582 { \
1583 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt()).asFloat(); \
1584 } \
1585 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1586 { \
1587 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt()).asFloat(); \
1588 } \
1589 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1590 { \
1591 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt()).asFloat(); \
1592 }
1593
1594 #define DECLARE_BINARY_INT_GENTYPE_FUNCS(FUNC_NAME) \
1595 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1596 { \
1597 c.color.x() = (float)FUNC_NAME((int)c.in[0].z(), (int)c.in[1].x()); \
1598 } \
1599 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1600 { \
1601 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1602 } \
1603 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1604 { \
1605 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1606 } \
1607 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1608 { \
1609 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1610 }
1611
1612 #define DECLARE_UNARY_UINT_GENTYPE_FUNCS(FUNC_NAME) \
1613 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1614 { \
1615 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z()); \
1616 } \
1617 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1618 { \
1619 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint()).asFloat(); \
1620 } \
1621 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1622 { \
1623 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint()).asFloat(); \
1624 } \
1625 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1626 { \
1627 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint()).asFloat(); \
1628 }
1629
1630 #define DECLARE_BINARY_UINT_GENTYPE_FUNCS(FUNC_NAME) \
1631 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1632 { \
1633 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x()); \
1634 } \
1635 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1636 { \
1637 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
1638 } \
1639 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1640 { \
1641 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
1642 } \
1643 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1644 { \
1645 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
1646 }
1647
1648 #define DECLARE_TERNARY_INT_GENTYPE_FUNCS(FUNC_NAME) \
1649 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1650 { \
1651 c.color.x() = (float)FUNC_NAME((int)c.in[0].z(), (int)c.in[1].x(), (int)c.in[2].y()); \
1652 } \
1653 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1654 { \
1655 c.color.yz() = \
1656 FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), c.in[1].swizzle(1, 0).asInt(), c.in[2].swizzle(2, 1).asInt()) \
1657 .asFloat(); \
1658 } \
1659 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1660 { \
1661 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), c.in[1].swizzle(1, 2, 0).asInt(), \
1662 c.in[2].swizzle(3, 1, 2).asInt()) \
1663 .asFloat(); \
1664 } \
1665 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1666 { \
1667 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), c.in[1].swizzle(3, 2, 1, 0).asInt(), \
1668 c.in[2].swizzle(0, 3, 2, 1).asInt()) \
1669 .asFloat(); \
1670 }
1671
1672 #define DECLARE_TERNARY_UINT_GENTYPE_FUNCS(FUNC_NAME) \
1673 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1674 { \
1675 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()); \
1676 } \
1677 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1678 { \
1679 c.color.yz() = \
1680 FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint(), c.in[2].swizzle(2, 1).asUint()) \
1681 .asFloat(); \
1682 } \
1683 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1684 { \
1685 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint(), \
1686 c.in[2].swizzle(3, 1, 2).asUint()) \
1687 .asFloat(); \
1688 } \
1689 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1690 { \
1691 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint(), \
1692 c.in[2].swizzle(0, 3, 2, 1).asUint()) \
1693 .asFloat(); \
1694 }
1695
1696 #define DECLARE_VEC_FLOAT_FUNCS(FUNC_NAME) \
1697 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1698 { \
1699 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].x()); \
1700 } \
1701 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1702 { \
1703 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].x()); \
1704 } \
1705 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1706 { \
1707 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].x()); \
1708 }
1709
1710 #define DECLARE_VEC_FLOAT_FLOAT_FUNCS(FUNC_NAME) \
1711 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1712 { \
1713 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].x(), c.in[2].y()); \
1714 } \
1715 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1716 { \
1717 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].x(), c.in[2].y()); \
1718 } \
1719 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1720 { \
1721 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].x(), c.in[2].y()); \
1722 }
1723
1724 #define DECLARE_VEC_VEC_FLOAT_FUNCS(FUNC_NAME) \
1725 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1726 { \
1727 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0), c.in[2].y()); \
1728 } \
1729 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1730 { \
1731 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0), c.in[2].y()); \
1732 } \
1733 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1734 { \
1735 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0), c.in[2].y()); \
1736 }
1737
1738 #define DECLARE_FLOAT_FLOAT_VEC_FUNCS(FUNC_NAME) \
1739 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1740 { \
1741 c.color.yz() = FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(2, 1)); \
1742 } \
1743 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1744 { \
1745 c.color.xyz() = FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(3, 1, 2)); \
1746 } \
1747 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1748 { \
1749 c.color = FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(0, 3, 2, 1)); \
1750 }
1751
1752 #define DECLARE_FLOAT_VEC_FUNCS(FUNC_NAME) \
1753 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1754 { \
1755 c.color.yz() = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(1, 0)); \
1756 } \
1757 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1758 { \
1759 c.color.xyz() = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(1, 2, 0)); \
1760 } \
1761 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1762 { \
1763 c.color = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(3, 2, 1, 0)); \
1764 }
1765
1766 #define DECLARE_IVEC_INT_FUNCS(FUNC_NAME) \
1767 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1768 { \
1769 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), (int)c.in[1].x()).asFloat(); \
1770 } \
1771 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1772 { \
1773 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), (int)c.in[1].x()).asFloat(); \
1774 } \
1775 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1776 { \
1777 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), (int)c.in[1].x()).asFloat(); \
1778 }
1779
1780 #define DECLARE_IVEC_INT_INT_FUNCS(FUNC_NAME) \
1781 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1782 { \
1783 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), (int)c.in[1].x(), (int)c.in[2].y()).asFloat(); \
1784 } \
1785 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1786 { \
1787 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), (int)c.in[1].x(), (int)c.in[2].y()).asFloat(); \
1788 } \
1789 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1790 { \
1791 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), (int)c.in[1].x(), (int)c.in[2].y()).asFloat(); \
1792 }
1793
1794 #define DECLARE_INT_IVEC_FUNCS(FUNC_NAME) \
1795 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1796 { \
1797 c.color.yz() = FUNC_NAME((int)c.in[0].z(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1798 } \
1799 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1800 { \
1801 c.color.xyz() = FUNC_NAME((int)c.in[0].z(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1802 } \
1803 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1804 { \
1805 c.color = FUNC_NAME((int)c.in[0].z(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1806 }
1807
1808 #define DECLARE_UVEC_UINT_FUNCS(FUNC_NAME) \
1809 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1810 { \
1811 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), (uint32_t)c.in[1].x()).asFloat(); \
1812 } \
1813 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1814 { \
1815 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), (uint32_t)c.in[1].x()).asFloat(); \
1816 } \
1817 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1818 { \
1819 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), (uint32_t)c.in[1].x()).asFloat(); \
1820 }
1821
1822 #define DECLARE_UVEC_UINT_UINT_FUNCS(FUNC_NAME) \
1823 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1824 { \
1825 c.color.yz() = \
1826 FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()).asFloat(); \
1827 } \
1828 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1829 { \
1830 c.color.xyz() = \
1831 FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()).asFloat(); \
1832 } \
1833 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1834 { \
1835 c.color = \
1836 FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()).asFloat(); \
1837 }
1838
1839 #define DECLARE_UINT_UVEC_FUNCS(FUNC_NAME) \
1840 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1841 { \
1842 c.color.yz() = FUNC_NAME((uint32_t)c.in[0].z(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
1843 } \
1844 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1845 { \
1846 c.color.xyz() = FUNC_NAME((uint32_t)c.in[0].z(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
1847 } \
1848 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1849 { \
1850 c.color = FUNC_NAME((uint32_t)c.in[0].z(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
1851 }
1852
1853 #define DECLARE_BINARY_INT_VEC_FUNCS(FUNC_NAME) \
1854 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1855 { \
1856 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1857 } \
1858 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1859 { \
1860 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1861 } \
1862 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1863 { \
1864 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1865 }
1866
1867 #define DECLARE_BINARY_UINT_VEC_FUNCS(FUNC_NAME) \
1868 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1869 { \
1870 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
1871 } \
1872 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1873 { \
1874 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
1875 } \
1876 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1877 { \
1878 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
1879 }
1880
1881 #define DECLARE_UINT_INT_GENTYPE_FUNCS(FUNC_NAME) \
1882 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1883 { \
1884 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (int)c.in[1].x()); \
1885 } \
1886 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1887 { \
1888 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1889 } \
1890 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1891 { \
1892 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1893 } \
1894 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1895 { \
1896 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1897 }
1898
1899 #define DECLARE_UVEC_INT_FUNCS(FUNC_NAME) \
1900 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1901 { \
1902 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), (int)c.in[1].x()).asFloat(); \
1903 } \
1904 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1905 { \
1906 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), (int)c.in[1].x()).asFloat(); \
1907 } \
1908 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1909 { \
1910 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), (int)c.in[1].x()).asFloat(); \
1911 }
1912
1913 // Operators.
1914
1915 DECLARE_UNARY_GENTYPE_FUNCS(nop)
DECLARE_UNARY_GENTYPE_FUNCS(negate)1916 DECLARE_UNARY_GENTYPE_FUNCS(negate)
1917 DECLARE_UNARY_GENTYPE_FUNCS(addOne)
1918 DECLARE_UNARY_GENTYPE_FUNCS(subOne)
1919 DECLARE_BINARY_GENTYPE_FUNCS(add)
1920 DECLARE_BINARY_GENTYPE_FUNCS(sub)
1921 DECLARE_BINARY_GENTYPE_FUNCS(mul)
1922 DECLARE_BINARY_GENTYPE_FUNCS(div)
1923
1924 void eval_selection_float(ShaderEvalContext &c)
1925 {
1926 c.color.x() = selection(c.in[0].z() > 0.0f, c.in[1].x(), c.in[2].y());
1927 }
eval_selection_vec2(ShaderEvalContext & c)1928 void eval_selection_vec2(ShaderEvalContext &c)
1929 {
1930 c.color.yz() = selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 0), c.in[2].swizzle(2, 1));
1931 }
eval_selection_vec3(ShaderEvalContext & c)1932 void eval_selection_vec3(ShaderEvalContext &c)
1933 {
1934 c.color.xyz() = selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 2, 0), c.in[2].swizzle(3, 1, 2));
1935 }
eval_selection_vec4(ShaderEvalContext & c)1936 void eval_selection_vec4(ShaderEvalContext &c)
1937 {
1938 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));
1939 }
1940
1941 DECLARE_UNARY_INT_GENTYPE_FUNCS(nop)
DECLARE_UNARY_INT_GENTYPE_FUNCS(negate)1942 DECLARE_UNARY_INT_GENTYPE_FUNCS(negate)
1943 DECLARE_UNARY_INT_GENTYPE_FUNCS(addOne)
1944 DECLARE_UNARY_INT_GENTYPE_FUNCS(subOne)
1945 DECLARE_UNARY_INT_GENTYPE_FUNCS(bitwiseNot)
1946 DECLARE_BINARY_INT_GENTYPE_FUNCS(add)
1947 DECLARE_BINARY_INT_GENTYPE_FUNCS(sub)
1948 DECLARE_BINARY_INT_GENTYPE_FUNCS(mul)
1949 DECLARE_BINARY_INT_GENTYPE_FUNCS(div)
1950 DECLARE_BINARY_INT_GENTYPE_FUNCS(mod)
1951 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseAnd)
1952 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseOr)
1953 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseXor)
1954
1955 void eval_leftShift_int(ShaderEvalContext &c)
1956 {
1957 c.color.x() = (float)leftShift((int)c.in[0].z(), (int)c.in[1].x());
1958 }
DECLARE_BINARY_INT_VEC_FUNCS(leftShift)1959 DECLARE_BINARY_INT_VEC_FUNCS(leftShift)
1960 void eval_rightShift_int(ShaderEvalContext &c)
1961 {
1962 c.color.x() = (float)rightShift((int)c.in[0].z(), (int)c.in[1].x());
1963 }
1964 DECLARE_BINARY_INT_VEC_FUNCS(rightShift)
DECLARE_IVEC_INT_FUNCS(leftShiftVecScalar)1965 DECLARE_IVEC_INT_FUNCS(leftShiftVecScalar)
1966 DECLARE_IVEC_INT_FUNCS(rightShiftVecScalar)
1967
1968 void eval_selection_int(ShaderEvalContext &c)
1969 {
1970 c.color.x() = (float)selection(c.in[0].z() > 0.0f, (int)c.in[1].x(), (int)c.in[2].y());
1971 }
eval_selection_ivec2(ShaderEvalContext & c)1972 void eval_selection_ivec2(ShaderEvalContext &c)
1973 {
1974 c.color.yz() =
1975 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 0).asInt(), c.in[2].swizzle(2, 1).asInt()).asFloat();
1976 }
eval_selection_ivec3(ShaderEvalContext & c)1977 void eval_selection_ivec3(ShaderEvalContext &c)
1978 {
1979 c.color.xyz() =
1980 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 2, 0).asInt(), c.in[2].swizzle(3, 1, 2).asInt()).asFloat();
1981 }
eval_selection_ivec4(ShaderEvalContext & c)1982 void eval_selection_ivec4(ShaderEvalContext &c)
1983 {
1984 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())
1985 .asFloat();
1986 }
1987
1988 DECLARE_UNARY_UINT_GENTYPE_FUNCS(nop)
DECLARE_UNARY_UINT_GENTYPE_FUNCS(negate)1989 DECLARE_UNARY_UINT_GENTYPE_FUNCS(negate)
1990 DECLARE_UNARY_UINT_GENTYPE_FUNCS(bitwiseNot)
1991 DECLARE_UNARY_UINT_GENTYPE_FUNCS(addOne)
1992 DECLARE_UNARY_UINT_GENTYPE_FUNCS(subOne)
1993 DECLARE_BINARY_UINT_GENTYPE_FUNCS(add)
1994 DECLARE_BINARY_UINT_GENTYPE_FUNCS(sub)
1995 DECLARE_BINARY_UINT_GENTYPE_FUNCS(mul)
1996 DECLARE_BINARY_UINT_GENTYPE_FUNCS(div)
1997 DECLARE_BINARY_UINT_GENTYPE_FUNCS(mod)
1998 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseAnd)
1999 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseOr)
2000 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseXor)
2001
2002 DECLARE_UINT_INT_GENTYPE_FUNCS(leftShift)
2003 DECLARE_UINT_INT_GENTYPE_FUNCS(rightShift)
2004 DECLARE_UVEC_INT_FUNCS(leftShiftVecScalar)
2005 DECLARE_UVEC_INT_FUNCS(rightShiftVecScalar)
2006
2007 void eval_selection_uint(ShaderEvalContext &c)
2008 {
2009 c.color.x() = (float)selection(c.in[0].z() > 0.0f, (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y());
2010 }
eval_selection_uvec2(ShaderEvalContext & c)2011 void eval_selection_uvec2(ShaderEvalContext &c)
2012 {
2013 c.color.yz() =
2014 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 0).asUint(), c.in[2].swizzle(2, 1).asUint()).asFloat();
2015 }
eval_selection_uvec3(ShaderEvalContext & c)2016 void eval_selection_uvec3(ShaderEvalContext &c)
2017 {
2018 c.color.xyz() =
2019 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 2, 0).asUint(), c.in[2].swizzle(3, 1, 2).asUint()).asFloat();
2020 }
eval_selection_uvec4(ShaderEvalContext & c)2021 void eval_selection_uvec4(ShaderEvalContext &c)
2022 {
2023 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())
2024 .asFloat();
2025 }
2026
2027 DECLARE_UNARY_BOOL_GENTYPE_FUNCS(boolNot)
DECLARE_BINARY_BOOL_FUNCS(logicalAnd)2028 DECLARE_BINARY_BOOL_FUNCS(logicalAnd)
2029 DECLARE_BINARY_BOOL_FUNCS(logicalOr)
2030 DECLARE_BINARY_BOOL_FUNCS(logicalXor)
2031
2032 void eval_selection_bool(ShaderEvalContext &c)
2033 {
2034 c.color.x() = (float)selection(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f, c.in[2].y() > 0.0f);
2035 }
eval_selection_bvec2(ShaderEvalContext & c)2036 void eval_selection_bvec2(ShaderEvalContext &c)
2037 {
2038 c.color.yz() = selection(c.in[0].z() > 0.0f, greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f, 0.0f)),
2039 greaterThan(c.in[2].swizzle(2, 1), Vec2(0.0f, 0.0f)))
2040 .asFloat();
2041 }
eval_selection_bvec3(ShaderEvalContext & c)2042 void eval_selection_bvec3(ShaderEvalContext &c)
2043 {
2044 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)),
2045 greaterThan(c.in[2].swizzle(3, 1, 2), Vec3(0.0f, 0.0f, 0.0f)))
2046 .asFloat();
2047 }
eval_selection_bvec4(ShaderEvalContext & c)2048 void eval_selection_bvec4(ShaderEvalContext &c)
2049 {
2050 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)),
2051 greaterThan(c.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f)))
2052 .asFloat();
2053 }
2054
2055 DECLARE_VEC_FLOAT_FUNCS(addVecScalar)
DECLARE_VEC_FLOAT_FUNCS(subVecScalar)2056 DECLARE_VEC_FLOAT_FUNCS(subVecScalar)
2057 DECLARE_VEC_FLOAT_FUNCS(mulVecScalar)
2058 DECLARE_VEC_FLOAT_FUNCS(divVecScalar)
2059
2060 DECLARE_FLOAT_VEC_FUNCS(addScalarVec)
2061 DECLARE_FLOAT_VEC_FUNCS(subScalarVec)
2062 DECLARE_FLOAT_VEC_FUNCS(mulScalarVec)
2063 DECLARE_FLOAT_VEC_FUNCS(divScalarVec)
2064
2065 DECLARE_IVEC_INT_FUNCS(addVecScalar)
2066 DECLARE_IVEC_INT_FUNCS(subVecScalar)
2067 DECLARE_IVEC_INT_FUNCS(mulVecScalar)
2068 DECLARE_IVEC_INT_FUNCS(divVecScalar)
2069 DECLARE_IVEC_INT_FUNCS(modVecScalar)
2070 DECLARE_IVEC_INT_FUNCS(bitwiseAndVecScalar)
2071 DECLARE_IVEC_INT_FUNCS(bitwiseOrVecScalar)
2072 DECLARE_IVEC_INT_FUNCS(bitwiseXorVecScalar)
2073
2074 DECLARE_INT_IVEC_FUNCS(addScalarVec)
2075 DECLARE_INT_IVEC_FUNCS(subScalarVec)
2076 DECLARE_INT_IVEC_FUNCS(mulScalarVec)
2077 DECLARE_INT_IVEC_FUNCS(divScalarVec)
2078 DECLARE_INT_IVEC_FUNCS(modScalarVec)
2079 DECLARE_INT_IVEC_FUNCS(bitwiseAndScalarVec)
2080 DECLARE_INT_IVEC_FUNCS(bitwiseOrScalarVec)
2081 DECLARE_INT_IVEC_FUNCS(bitwiseXorScalarVec)
2082
2083 DECLARE_UVEC_UINT_FUNCS(addVecScalar)
2084 DECLARE_UVEC_UINT_FUNCS(subVecScalar)
2085 DECLARE_UVEC_UINT_FUNCS(mulVecScalar)
2086 DECLARE_UVEC_UINT_FUNCS(divVecScalar)
2087 DECLARE_UVEC_UINT_FUNCS(modVecScalar)
2088 DECLARE_UVEC_UINT_FUNCS(bitwiseAndVecScalar)
2089 DECLARE_UVEC_UINT_FUNCS(bitwiseOrVecScalar)
2090 DECLARE_UVEC_UINT_FUNCS(bitwiseXorVecScalar)
2091
2092 DECLARE_UINT_UVEC_FUNCS(addScalarVec)
2093 DECLARE_UINT_UVEC_FUNCS(subScalarVec)
2094 DECLARE_UINT_UVEC_FUNCS(mulScalarVec)
2095 DECLARE_UINT_UVEC_FUNCS(divScalarVec)
2096 DECLARE_UINT_UVEC_FUNCS(modScalarVec)
2097 DECLARE_UINT_UVEC_FUNCS(bitwiseAndScalarVec)
2098 DECLARE_UINT_UVEC_FUNCS(bitwiseOrScalarVec)
2099 DECLARE_UINT_UVEC_FUNCS(bitwiseXorScalarVec)
2100
2101 // Built-in functions.
2102
2103 DECLARE_UNARY_GENTYPE_FUNCS(radians)
2104 DECLARE_UNARY_GENTYPE_FUNCS(degrees)
2105 DECLARE_UNARY_GENTYPE_FUNCS(sin)
2106 DECLARE_UNARY_GENTYPE_FUNCS(cos)
2107 DECLARE_UNARY_GENTYPE_FUNCS(tan)
2108 DECLARE_UNARY_GENTYPE_FUNCS(asin)
2109 DECLARE_UNARY_GENTYPE_FUNCS(acos)
2110 DECLARE_UNARY_GENTYPE_FUNCS(atan)
2111 DECLARE_BINARY_GENTYPE_FUNCS(atan2)
2112 DECLARE_UNARY_GENTYPE_FUNCS(sinh)
2113 DECLARE_UNARY_GENTYPE_FUNCS(cosh)
2114 DECLARE_UNARY_GENTYPE_FUNCS(tanh)
2115 DECLARE_UNARY_GENTYPE_FUNCS(asinh)
2116 DECLARE_UNARY_GENTYPE_FUNCS(acosh)
2117 DECLARE_UNARY_GENTYPE_FUNCS(atanh)
2118
2119 DECLARE_BINARY_GENTYPE_FUNCS(pow)
2120 DECLARE_UNARY_GENTYPE_FUNCS(exp)
2121 DECLARE_UNARY_GENTYPE_FUNCS(log)
2122 DECLARE_UNARY_GENTYPE_FUNCS(exp2)
2123 DECLARE_UNARY_GENTYPE_FUNCS(log2)
2124 DECLARE_UNARY_GENTYPE_FUNCS(sqrt)
2125 DECLARE_UNARY_GENTYPE_FUNCS(inverseSqrt)
2126
2127 DECLARE_UNARY_GENTYPE_FUNCS(abs)
2128 DECLARE_UNARY_GENTYPE_FUNCS(sign)
2129 DECLARE_UNARY_GENTYPE_FUNCS(floor)
2130 DECLARE_UNARY_GENTYPE_FUNCS(trunc)
2131 DECLARE_UNARY_GENTYPE_FUNCS(roundToEven)
2132 DECLARE_UNARY_GENTYPE_FUNCS(ceil)
2133 DECLARE_UNARY_GENTYPE_FUNCS(fract)
2134 DECLARE_BINARY_GENTYPE_FUNCS(mod)
2135 DECLARE_VEC_FLOAT_FUNCS(modVecScalar)
2136 DECLARE_BINARY_GENTYPE_FUNCS(min)
2137 DECLARE_VEC_FLOAT_FUNCS(minVecScalar)
2138 DECLARE_BINARY_INT_GENTYPE_FUNCS(min)
2139 DECLARE_IVEC_INT_FUNCS(minVecScalar)
2140 DECLARE_BINARY_UINT_GENTYPE_FUNCS(min)
2141 DECLARE_UVEC_UINT_FUNCS(minVecScalar)
2142 DECLARE_BINARY_GENTYPE_FUNCS(max)
2143 DECLARE_VEC_FLOAT_FUNCS(maxVecScalar)
2144 DECLARE_BINARY_INT_GENTYPE_FUNCS(max)
2145 DECLARE_IVEC_INT_FUNCS(maxVecScalar)
2146 DECLARE_BINARY_UINT_GENTYPE_FUNCS(max)
2147 DECLARE_UVEC_UINT_FUNCS(maxVecScalar)
2148 DECLARE_TERNARY_GENTYPE_FUNCS(clamp)
2149 DECLARE_VEC_FLOAT_FLOAT_FUNCS(clampVecScalarScalar)
2150 DECLARE_TERNARY_INT_GENTYPE_FUNCS(clamp)
2151 DECLARE_IVEC_INT_INT_FUNCS(clampVecScalarScalar)
2152 DECLARE_TERNARY_UINT_GENTYPE_FUNCS(clamp)
2153 DECLARE_UVEC_UINT_UINT_FUNCS(clampVecScalarScalar)
2154 DECLARE_TERNARY_GENTYPE_FUNCS(mix)
2155 DECLARE_VEC_VEC_FLOAT_FUNCS(mixVecVecScalar)
2156 DECLARE_BINARY_GENTYPE_FUNCS(step)
2157 DECLARE_FLOAT_VEC_FUNCS(stepScalarVec)
2158 DECLARE_TERNARY_GENTYPE_FUNCS(smoothStep)
2159 DECLARE_FLOAT_FLOAT_VEC_FUNCS(smoothStepScalarScalarVec)
2160
2161 DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(length)
2162 DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(distance)
2163 DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(dot)
2164 void eval_cross_vec3(ShaderEvalContext &c)
2165 {
2166 c.color.xyz() = cross(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0));
2167 }
2168
2169 DECLARE_UNARY_GENTYPE_FUNCS(normalize)
DECLARE_TERNARY_GENTYPE_FUNCS(faceForward)2170 DECLARE_TERNARY_GENTYPE_FUNCS(faceForward)
2171 DECLARE_BINARY_GENTYPE_FUNCS(reflect)
2172
2173 void eval_refract_float(ShaderEvalContext &c)
2174 {
2175 c.color.x() = refract(c.in[0].z(), c.in[1].x(), c.in[2].y());
2176 }
eval_refract_vec2(ShaderEvalContext & c)2177 void eval_refract_vec2(ShaderEvalContext &c)
2178 {
2179 c.color.yz() = refract(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0), c.in[2].y());
2180 }
eval_refract_vec3(ShaderEvalContext & c)2181 void eval_refract_vec3(ShaderEvalContext &c)
2182 {
2183 c.color.xyz() = refract(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0), c.in[2].y());
2184 }
eval_refract_vec4(ShaderEvalContext & c)2185 void eval_refract_vec4(ShaderEvalContext &c)
2186 {
2187 c.color = refract(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0), c.in[2].y());
2188 }
2189
2190 // Compare functions.
2191
2192 #define DECLARE_FLOAT_COMPARE_FUNCS(FUNC_NAME) \
2193 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
2194 { \
2195 c.color.x() = (float)FUNC_NAME(c.in[0].z(), c.in[1].x()); \
2196 } \
2197 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
2198 { \
2199 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); \
2200 } \
2201 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
2202 { \
2203 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); \
2204 } \
2205 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
2206 { \
2207 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); \
2208 }
2209
2210 #define DECLARE_FLOAT_CWISE_COMPARE_FUNCS(FUNC_NAME) \
2211 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
2212 { \
2213 c.color.x() = (float)FUNC_NAME(c.in[0].z(), c.in[1].x()); \
2214 } \
2215 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
2216 { \
2217 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)).asFloat(); \
2218 } \
2219 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
2220 { \
2221 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)).asFloat(); \
2222 } \
2223 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
2224 { \
2225 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)).asFloat(); \
2226 }
2227
2228 #define DECLARE_INT_COMPARE_FUNCS(FUNC_NAME) \
2229 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
2230 { \
2231 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); \
2232 } \
2233 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
2234 { \
2235 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].swizzle(3, 1)), chopToInt(c.in[1].swizzle(1, 0))); \
2236 } \
2237 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
2238 { \
2239 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].swizzle(2, 0, 1)), chopToInt(c.in[1].swizzle(1, 2, 0))); \
2240 } \
2241 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
2242 { \
2243 c.color.x() = \
2244 (float)FUNC_NAME(chopToInt(c.in[0].swizzle(1, 2, 3, 0)), chopToInt(c.in[1].swizzle(3, 2, 1, 0))); \
2245 }
2246
2247 #define DECLARE_INT_CWISE_COMPARE_FUNCS(FUNC_NAME) \
2248 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
2249 { \
2250 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); \
2251 } \
2252 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
2253 { \
2254 c.color.yz() = FUNC_NAME(chopToInt(c.in[0].swizzle(3, 1)), chopToInt(c.in[1].swizzle(1, 0))).asFloat(); \
2255 } \
2256 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
2257 { \
2258 c.color.xyz() = FUNC_NAME(chopToInt(c.in[0].swizzle(2, 0, 1)), chopToInt(c.in[1].swizzle(1, 2, 0))).asFloat(); \
2259 } \
2260 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
2261 { \
2262 c.color = FUNC_NAME(chopToInt(c.in[0].swizzle(1, 2, 3, 0)), chopToInt(c.in[1].swizzle(3, 2, 1, 0))).asFloat(); \
2263 }
2264
2265 #define DECLARE_UINT_COMPARE_FUNCS(FUNC_NAME) \
2266 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
2267 { \
2268 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x()); \
2269 } \
2270 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
2271 { \
2272 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()); \
2273 } \
2274 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
2275 { \
2276 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()); \
2277 } \
2278 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
2279 { \
2280 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()); \
2281 }
2282
2283 #define DECLARE_UINT_CWISE_COMPARE_FUNCS(FUNC_NAME) \
2284 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
2285 { \
2286 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x()); \
2287 } \
2288 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
2289 { \
2290 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
2291 } \
2292 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
2293 { \
2294 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
2295 } \
2296 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
2297 { \
2298 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
2299 }
2300
2301 #define DECLARE_BOOL_COMPARE_FUNCS(FUNC_NAME) \
2302 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
2303 { \
2304 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); \
2305 } \
2306 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
2307 { \
2308 c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)), \
2309 greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f))); \
2310 } \
2311 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
2312 { \
2313 c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)), \
2314 greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f))); \
2315 } \
2316 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
2317 { \
2318 c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), \
2319 greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f))); \
2320 }
2321
2322 #define DECLARE_BOOL_CWISE_COMPARE_FUNCS(FUNC_NAME) \
2323 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
2324 { \
2325 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); \
2326 } \
2327 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
2328 { \
2329 c.color.yz() = \
2330 FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)), greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f))) \
2331 .asFloat(); \
2332 } \
2333 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
2334 { \
2335 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)), \
2336 greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f))) \
2337 .asFloat(); \
2338 } \
2339 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
2340 { \
2341 c.color = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), \
2342 greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f))) \
2343 .asFloat(); \
2344 }
2345
2346 DECLARE_FLOAT_COMPARE_FUNCS(allEqual)
DECLARE_FLOAT_COMPARE_FUNCS(anyNotEqual)2347 DECLARE_FLOAT_COMPARE_FUNCS(anyNotEqual)
2348 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThan)
2349 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThanEqual)
2350 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThan)
2351 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThanEqual)
2352 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(equal)
2353 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(notEqual)
2354
2355 DECLARE_INT_COMPARE_FUNCS(allEqual)
2356 DECLARE_INT_COMPARE_FUNCS(anyNotEqual)
2357 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThan)
2358 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThanEqual)
2359 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThan)
2360 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThanEqual)
2361 DECLARE_INT_CWISE_COMPARE_FUNCS(equal)
2362 DECLARE_INT_CWISE_COMPARE_FUNCS(notEqual)
2363
2364 DECLARE_UINT_COMPARE_FUNCS(allEqual)
2365 DECLARE_UINT_COMPARE_FUNCS(anyNotEqual)
2366 DECLARE_UINT_CWISE_COMPARE_FUNCS(lessThan)
2367 DECLARE_UINT_CWISE_COMPARE_FUNCS(lessThanEqual)
2368 DECLARE_UINT_CWISE_COMPARE_FUNCS(greaterThan)
2369 DECLARE_UINT_CWISE_COMPARE_FUNCS(greaterThanEqual)
2370 DECLARE_UINT_CWISE_COMPARE_FUNCS(equal)
2371 DECLARE_UINT_CWISE_COMPARE_FUNCS(notEqual)
2372
2373 DECLARE_BOOL_COMPARE_FUNCS(allEqual)
2374 DECLARE_BOOL_COMPARE_FUNCS(anyNotEqual)
2375 DECLARE_BOOL_CWISE_COMPARE_FUNCS(equal)
2376 DECLARE_BOOL_CWISE_COMPARE_FUNCS(notEqual)
2377
2378 // Boolean functions.
2379
2380 #define DECLARE_UNARY_SCALAR_BVEC_FUNCS(GLSL_NAME, FUNC_NAME) \
2381 void eval_##GLSL_NAME##_bvec2(ShaderEvalContext &c) \
2382 { \
2383 c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)))); \
2384 } \
2385 void eval_##GLSL_NAME##_bvec3(ShaderEvalContext &c) \
2386 { \
2387 c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)))); \
2388 } \
2389 void eval_##GLSL_NAME##_bvec4(ShaderEvalContext &c) \
2390 { \
2391 c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)))); \
2392 }
2393
2394 #define DECLARE_UNARY_BVEC_BVEC_FUNCS(GLSL_NAME, FUNC_NAME) \
2395 void eval_##GLSL_NAME##_bvec2(ShaderEvalContext &c) \
2396 { \
2397 c.color.yz() = FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); \
2398 } \
2399 void eval_##GLSL_NAME##_bvec3(ShaderEvalContext &c) \
2400 { \
2401 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); \
2402 } \
2403 void eval_##GLSL_NAME##_bvec4(ShaderEvalContext &c) \
2404 { \
2405 c.color.xyzw() = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f))).asFloat(); \
2406 }
2407
2408 DECLARE_UNARY_SCALAR_BVEC_FUNCS(any, boolAny)
2409 DECLARE_UNARY_SCALAR_BVEC_FUNCS(all, boolAll)
2410
2411 void ShaderOperatorTests::init(void)
2412 {
2413 #define BOOL_FUNCS(FUNC_NAME) eval_##FUNC_NAME##_bool, DE_NULL, DE_NULL, DE_NULL
2414
2415 #define FLOAT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4
2416 #define INT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4
2417 #define UINT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_uvec2, eval_##FUNC_NAME##_uvec3, eval_##FUNC_NAME##_uvec4
2418 #define BOOL_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4
2419
2420 #define FLOAT_GENTYPE_FUNCS(FUNC_NAME) \
2421 eval_##FUNC_NAME##_float, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4
2422 #define INT_GENTYPE_FUNCS(FUNC_NAME) \
2423 eval_##FUNC_NAME##_int, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4
2424 #define UINT_GENTYPE_FUNCS(FUNC_NAME) \
2425 eval_##FUNC_NAME##_uint, eval_##FUNC_NAME##_uvec2, eval_##FUNC_NAME##_uvec3, eval_##FUNC_NAME##_uvec4
2426 #define BOOL_GENTYPE_FUNCS(FUNC_NAME) \
2427 eval_##FUNC_NAME##_bool, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4
2428
2429 // Shorthands.
2430 Value notUsed = Value(VALUE_NONE, 0.0f, 0.0f);
2431 FloatScalar::Symbol lUMax = FloatScalar::SYMBOL_LOWP_UINT_MAX;
2432 FloatScalar::Symbol mUMax = FloatScalar::SYMBOL_MEDIUMP_UINT_MAX;
2433 FloatScalar::Symbol lUMaxR = FloatScalar::SYMBOL_LOWP_UINT_MAX_RECIPROCAL;
2434 FloatScalar::Symbol mUMaxR = FloatScalar::SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL;
2435
2436 std::vector<BuiltinFuncGroup> funcInfoGroups;
2437
2438 // Unary operators.
2439 funcInfoGroups.push_back(
2440 BuiltinFuncGroup("unary_operator", "Unary operator tests")
2441 << BuiltinOperInfo("plus", "+", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL,
2442 FLOAT_GENTYPE_FUNCS(nop))
2443 << BuiltinOperInfo("plus", "+", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL,
2444 INT_GENTYPE_FUNCS(nop))
2445 << BuiltinOperInfo("plus", "+", UGT, Value(UGT, 0.0f, 2e2f), notUsed, notUsed, 5e-3f, 0.0f, PRECMASK_ALL,
2446 UINT_GENTYPE_FUNCS(nop))
2447 << BuiltinOperInfo("minus", "-", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL,
2448 FLOAT_GENTYPE_FUNCS(negate))
2449 << BuiltinOperInfo("minus", "-", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL,
2450 INT_GENTYPE_FUNCS(negate))
2451 << BuiltinOperInfoSeparateRefScaleBias("minus", "-", UGT, Value(UGT, 0.0f, lUMax), notUsed, notUsed, lUMaxR,
2452 0.0f, PRECMASK_LOWP, UINT_GENTYPE_FUNCS(negate), lUMaxR,
2453 FloatScalar::SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX)
2454 << BuiltinOperInfoSeparateRefScaleBias("minus", "-", UGT, Value(UGT, 0.0f, mUMax), notUsed, notUsed, mUMaxR,
2455 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(negate), mUMaxR,
2456 FloatScalar::SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX)
2457 << BuiltinOperInfo("minus", "-", UGT, Value(UGT, 0.0f, 4e9f), notUsed, notUsed, 2e-10f, 0.0f, PRECMASK_HIGHP,
2458 UINT_GENTYPE_FUNCS(negate))
2459 << BuiltinOperInfo("not", "!", B, Value(B, -1.0f, 1.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_NA,
2460 eval_boolNot_bool, DE_NULL, DE_NULL, DE_NULL)
2461 << BuiltinOperInfo("bitwise_not", "~", IGT, Value(IGT, -1e5f, 1e5f), notUsed, notUsed, 5e-5f, 0.5f,
2462 PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseNot))
2463 << BuiltinOperInfo("bitwise_not", "~", UGT, Value(UGT, 0.0f, 2e9f), notUsed, notUsed, 2e-10f, 0.0f,
2464 PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseNot))
2465
2466 // Pre/post incr/decr side effect cases.
2467 << BuiltinSideEffOperInfo("pre_increment_effect", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2468 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne))
2469 << BuiltinSideEffOperInfo("pre_increment_effect", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed, 0.1f,
2470 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne))
2471 << BuiltinSideEffOperInfo("pre_increment_effect", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed, 0.1f,
2472 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(addOne))
2473 << BuiltinSideEffOperInfo("pre_decrement_effect", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2474 1.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne))
2475 << BuiltinSideEffOperInfo("pre_decrement_effect", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed, 0.1f,
2476 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne))
2477 << BuiltinSideEffOperInfo("pre_decrement_effect", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed, 0.1f,
2478 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(subOne))
2479 << BuiltinPostSideEffOperInfo("post_increment_effect", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2480 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne))
2481 << BuiltinPostSideEffOperInfo("post_increment_effect", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed,
2482 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne))
2483 << BuiltinPostSideEffOperInfo("post_increment_effect", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed,
2484 0.1f, 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(addOne))
2485 << BuiltinPostSideEffOperInfo("post_decrement_effect", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2486 1.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne))
2487 << BuiltinPostSideEffOperInfo("post_decrement_effect", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed,
2488 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne))
2489 << BuiltinPostSideEffOperInfo("post_decrement_effect", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed,
2490 0.1f, 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(subOne))
2491
2492 // Pre/post incr/decr result cases.
2493 << BuiltinOperInfo("pre_increment_result", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.0f,
2494 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne))
2495 << BuiltinOperInfo("pre_increment_result", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed, 0.1f, 0.5f,
2496 PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne))
2497 << BuiltinOperInfo("pre_increment_result", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed, 0.1f, 0.0f,
2498 PRECMASK_ALL, UINT_GENTYPE_FUNCS(addOne))
2499 << BuiltinOperInfo("pre_decrement_result", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 1.0f,
2500 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne))
2501 << BuiltinOperInfo("pre_decrement_result", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed, 0.1f, 0.5f,
2502 PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne))
2503 << BuiltinOperInfo("pre_decrement_result", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed, 0.1f, 0.0f,
2504 PRECMASK_ALL, UINT_GENTYPE_FUNCS(subOne))
2505 << BuiltinPostOperInfo("post_increment_result", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f,
2506 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(nop))
2507 << BuiltinPostOperInfo("post_increment_result", "++", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f,
2508 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(nop))
2509 << BuiltinPostOperInfo("post_increment_result", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed, 0.1f, 0.0f,
2510 PRECMASK_ALL, UINT_GENTYPE_FUNCS(nop))
2511 << BuiltinPostOperInfo("post_decrement_result", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f,
2512 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(nop))
2513 << BuiltinPostOperInfo("post_decrement_result", "--", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f,
2514 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(nop))
2515 << BuiltinPostOperInfo("post_decrement_result", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed, 0.1f,
2516 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(nop)));
2517
2518 BuiltinFuncGroup binaryOpGroup("binary_operator", "Binary operator tests");
2519
2520 // Normal binary operations and their corresponding assignment operations have lots in common; generate both in the following loop.
2521
2522 for (int binaryOperatorType = 0; binaryOperatorType <= 2;
2523 binaryOperatorType++) // 0: normal op test, 1: assignment op side-effect test, 2: assignment op result test
2524 {
2525 bool isNormalOp = binaryOperatorType == 0;
2526 bool isAssignEff = binaryOperatorType == 1;
2527 bool isAssignRes = binaryOperatorType == 2;
2528
2529 DE_ASSERT(isNormalOp || isAssignEff || isAssignRes);
2530 DE_UNREF(isAssignRes);
2531
2532 const char *addName = isNormalOp ? "add" : isAssignEff ? "add_assign_effect" : "add_assign_result";
2533 const char *subName = isNormalOp ? "sub" : isAssignEff ? "sub_assign_effect" : "sub_assign_result";
2534 const char *mulName = isNormalOp ? "mul" : isAssignEff ? "mul_assign_effect" : "mul_assign_result";
2535 const char *divName = isNormalOp ? "div" : isAssignEff ? "div_assign_effect" : "div_assign_result";
2536 const char *modName = isNormalOp ? "mod" : isAssignEff ? "mod_assign_effect" : "mod_assign_result";
2537 const char *andName = isNormalOp ? "bitwise_and" :
2538 isAssignEff ? "bitwise_and_assign_effect" :
2539 "bitwise_and_assign_result";
2540 const char *orName = isNormalOp ? "bitwise_or" :
2541 isAssignEff ? "bitwise_or_assign_effect" :
2542 "bitwise_or_assign_result";
2543 const char *xorName = isNormalOp ? "bitwise_xor" :
2544 isAssignEff ? "bitwise_xor_assign_effect" :
2545 "bitwise_xor_assign_result";
2546 const char *leftShiftName = isNormalOp ? "left_shift" :
2547 isAssignEff ? "left_shift_assign_effect" :
2548 "left_shift_assign_result";
2549 const char *rightShiftName = isNormalOp ? "right_shift" :
2550 isAssignEff ? "right_shift_assign_effect" :
2551 "right_shift_assign_result";
2552 const char *addOp = isNormalOp ? "+" : "+=";
2553 const char *subOp = isNormalOp ? "-" : "-=";
2554 const char *mulOp = isNormalOp ? "*" : "*=";
2555 const char *divOp = isNormalOp ? "/" : "/=";
2556 const char *modOp = isNormalOp ? "%" : "%=";
2557 const char *andOp = isNormalOp ? "&" : "&=";
2558 const char *orOp = isNormalOp ? "|" : "|=";
2559 const char *xorOp = isNormalOp ? "^" : "^=";
2560 const char *leftShiftOp = isNormalOp ? "<<" : "<<=";
2561 const char *rightShiftOp = isNormalOp ? ">>" : ">>=";
2562
2563 // Pointer to appropriate OperInfo function.
2564 BuiltinFuncInfo (*operInfoFunc)(const char *, const char *, ValueType, Value, Value, Value, const FloatScalar &,
2565 const FloatScalar &, uint32_t, ShaderEvalFunc, ShaderEvalFunc, ShaderEvalFunc,
2566 ShaderEvalFunc) = isAssignEff ? BuiltinSideEffOperInfo : BuiltinOperInfo;
2567
2568 DE_ASSERT(operInfoFunc != DE_NULL);
2569
2570 // The following cases will be added for each operator, precision and fundamental type (float, int, uint) combination, where applicable:
2571 // gentype <op> gentype
2572 // vector <op> scalar
2573 // For normal (non-assigning) operators only:
2574 // scalar <op> vector
2575
2576 // The add operator.
2577
2578 binaryOpGroup << operInfoFunc(addName, addOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f,
2579 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(add))
2580 << operInfoFunc(addName, addOp, IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed,
2581 0.1f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(add))
2582 << operInfoFunc(addName, addOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2583 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(add))
2584 << operInfoFunc(addName, addOp, UGT, Value(UGT, 0.0f, 1e2f), Value(UGT, 0.0f, 1e2f), notUsed,
2585 5e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(add))
2586 << operInfoFunc(addName, addOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2587 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(add))
2588 << operInfoFunc(addName, addOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2589 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addVecScalar))
2590 << operInfoFunc(addName, addOp, IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f,
2591 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(addVecScalar))
2592 << operInfoFunc(addName, addOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2593 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(addVecScalar))
2594 << operInfoFunc(addName, addOp, UV, Value(UV, 0.0f, 1e2f), Value(U, 0.0f, 1e2f), notUsed, 5e-3f,
2595 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(addVecScalar))
2596 << operInfoFunc(addName, addOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2597 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(addVecScalar));
2598
2599 if (isNormalOp)
2600 binaryOpGroup << operInfoFunc(addName, addOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
2601 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addScalarVec))
2602 << operInfoFunc(addName, addOp, IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed,
2603 0.1f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(addScalarVec))
2604 << operInfoFunc(addName, addOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2605 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(addScalarVec))
2606 << operInfoFunc(addName, addOp, UV, Value(U, 0.0f, 1e2f), Value(UV, 0.0f, 1e2f), notUsed,
2607 5e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(addScalarVec))
2608 << operInfoFunc(addName, addOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2609 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(addScalarVec));
2610
2611 // The subtract operator.
2612
2613 binaryOpGroup << operInfoFunc(subName, subOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f,
2614 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(sub))
2615 << operInfoFunc(subName, subOp, IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed,
2616 0.1f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(sub))
2617 << operInfoFunc(subName, subOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2618 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(sub))
2619 << operInfoFunc(subName, subOp, UGT, Value(UGT, 1e2f, 2e2f), Value(UGT, 0.0f, 1e2f), notUsed,
2620 5e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(sub))
2621 << operInfoFunc(subName, subOp, UGT, Value(UGT, .5e9f, 3.7e9f), Value(UGT, 0.0f, 3.9e9f), notUsed,
2622 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(sub))
2623 << operInfoFunc(subName, subOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2624 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subVecScalar))
2625 << operInfoFunc(subName, subOp, IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f,
2626 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(subVecScalar))
2627 << operInfoFunc(subName, subOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2628 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(subVecScalar))
2629 << operInfoFunc(subName, subOp, UV, Value(UV, 1e2f, 2e2f), Value(U, 0.0f, 1e2f), notUsed, 5e-3f,
2630 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(subVecScalar))
2631 << operInfoFunc(subName, subOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2632 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(subVecScalar));
2633
2634 if (isNormalOp)
2635 binaryOpGroup << operInfoFunc(subName, subOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
2636 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subScalarVec))
2637 << operInfoFunc(subName, subOp, IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed,
2638 0.1f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(subScalarVec))
2639 << operInfoFunc(subName, subOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2640 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(subScalarVec))
2641 << operInfoFunc(subName, subOp, UV, Value(U, 1e2f, 2e2f), Value(UV, 0.0f, 1e2f), notUsed,
2642 5e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(subScalarVec))
2643 << operInfoFunc(subName, subOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2644 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(subScalarVec));
2645
2646 // The multiply operator.
2647
2648 binaryOpGroup << operInfoFunc(mulName, mulOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f,
2649 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(mul))
2650 << operInfoFunc(mulName, mulOp, IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed,
2651 0.1f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(mul))
2652 << operInfoFunc(mulName, mulOp, IGT, Value(IGT, -3e5f, 3e5f), Value(IGT, -3e4f, 3e4f), notUsed,
2653 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(mul))
2654 << operInfoFunc(mulName, mulOp, UGT, Value(UGT, 0.0f, 16.0f), Value(UGT, 0.0f, 16.0f), notUsed,
2655 4e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(mul))
2656 << operInfoFunc(mulName, mulOp, UGT, Value(UGT, 0.0f, 6e5f), Value(UGT, 0.0f, 6e4f), notUsed,
2657 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(mul))
2658 << operInfoFunc(mulName, mulOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2659 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulVecScalar))
2660 << operInfoFunc(mulName, mulOp, IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f,
2661 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(mulVecScalar))
2662 << operInfoFunc(mulName, mulOp, IV, Value(IV, -3e5f, 3e5f), Value(I, -3e4f, 3e4f), notUsed,
2663 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(mulVecScalar))
2664 << operInfoFunc(mulName, mulOp, UV, Value(UV, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 4e-3f,
2665 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(mulVecScalar))
2666 << operInfoFunc(mulName, mulOp, UV, Value(UV, 0.0f, 6e5f), Value(U, 0.0f, 6e4f), notUsed, 2e-10f,
2667 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(mulVecScalar));
2668
2669 if (isNormalOp)
2670 binaryOpGroup << operInfoFunc(mulName, mulOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
2671 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulScalarVec))
2672 << operInfoFunc(mulName, mulOp, IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed,
2673 0.1f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(mulScalarVec))
2674 << operInfoFunc(mulName, mulOp, IV, Value(I, -3e5f, 3e5f), Value(IV, -3e4f, 3e4f), notUsed,
2675 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(mulScalarVec))
2676 << operInfoFunc(mulName, mulOp, UV, Value(U, 0.0f, 16.0f), Value(UV, 0.0f, 16.0f), notUsed,
2677 4e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(mulScalarVec))
2678 << operInfoFunc(mulName, mulOp, UV, Value(U, 0.0f, 6e5f), Value(UV, 0.0f, 6e4f), notUsed,
2679 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(mulScalarVec));
2680
2681 // The divide operator.
2682
2683 binaryOpGroup << operInfoFunc(divName, divOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -2.0f, -0.5f), notUsed,
2684 1.0f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(div))
2685 << operInfoFunc(divName, divOp, IGT, Value(IGT, 24.0f, 24.0f), Value(IGT, -4.0f, -1.0f), notUsed,
2686 0.04f, 1.0f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(div))
2687 << operInfoFunc(divName, divOp, IGT, Value(IGT, 40320.0f, 40320.0f), Value(IGT, -8.0f, -1.0f),
2688 notUsed, 1e-5f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(div))
2689 << operInfoFunc(divName, divOp, UGT, Value(UGT, 0.0f, 24.0f), Value(UGT, 1.0f, 4.0f), notUsed,
2690 0.04f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(div))
2691 << operInfoFunc(divName, divOp, UGT, Value(UGT, 0.0f, 40320.0f), Value(UGT, 1.0f, 8.0f), notUsed,
2692 1e-5f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(div))
2693 << operInfoFunc(divName, divOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -2.0f, -0.5f), notUsed, 1.0f,
2694 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divVecScalar))
2695 << operInfoFunc(divName, divOp, IV, Value(IV, 24.0f, 24.0f), Value(I, -4.0f, -1.0f), notUsed,
2696 0.04f, 1.0f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(divVecScalar))
2697 << operInfoFunc(divName, divOp, IV, Value(IV, 40320.0f, 40320.0f), Value(I, -8.0f, -1.0f),
2698 notUsed, 1e-5f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(divVecScalar))
2699 << operInfoFunc(divName, divOp, UV, Value(UV, 0.0f, 24.0f), Value(U, 1.0f, 4.0f), notUsed, 0.04f,
2700 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(divVecScalar))
2701 << operInfoFunc(divName, divOp, UV, Value(UV, 0.0f, 40320.0f), Value(U, 1.0f, 8.0f), notUsed,
2702 1e-5f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(divVecScalar));
2703
2704 if (isNormalOp)
2705 binaryOpGroup << operInfoFunc(divName, divOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -2.0f, -0.5f), notUsed,
2706 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divScalarVec))
2707 << operInfoFunc(divName, divOp, IV, Value(I, 24.0f, 24.0f), Value(IV, -4.0f, -1.0f), notUsed,
2708 0.04f, 1.0f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(divScalarVec))
2709 << operInfoFunc(divName, divOp, IV, Value(I, 40320.0f, 40320.0f), Value(IV, -8.0f, -1.0f),
2710 notUsed, 1e-5f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(divScalarVec))
2711 << operInfoFunc(divName, divOp, UV, Value(U, 0.0f, 24.0f), Value(UV, 1.0f, 4.0f), notUsed,
2712 0.04f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(divScalarVec))
2713 << operInfoFunc(divName, divOp, UV, Value(U, 0.0f, 40320.0f), Value(UV, 1.0f, 8.0f), notUsed,
2714 1e-5f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(divScalarVec));
2715
2716 // The modulus operator.
2717
2718 binaryOpGroup << operInfoFunc(modName, modOp, IGT, Value(IGT, 0.0f, 6.0f), Value(IGT, 1.1f, 6.1f), notUsed,
2719 0.25f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(mod))
2720 << operInfoFunc(modName, modOp, IGT, Value(IGT, 0.0f, 14.0f), Value(IGT, 1.1f, 11.1f), notUsed,
2721 0.1f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(mod))
2722 << operInfoFunc(modName, modOp, UGT, Value(UGT, 0.0f, 6.0f), Value(UGT, 1.1f, 6.1f), notUsed,
2723 0.25f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(mod))
2724 << operInfoFunc(modName, modOp, UGT, Value(UGT, 0.0f, 24.0f), Value(UGT, 1.1f, 11.1f), notUsed,
2725 0.1f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(mod))
2726 << operInfoFunc(modName, modOp, IV, Value(IV, 0.0f, 6.0f), Value(I, 1.1f, 6.1f), notUsed, 0.25f,
2727 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(modVecScalar))
2728 << operInfoFunc(modName, modOp, IV, Value(IV, 0.0f, 6.0f), Value(I, 1.1f, 11.1f), notUsed, 0.1f,
2729 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(modVecScalar))
2730 << operInfoFunc(modName, modOp, UV, Value(UV, 0.0f, 6.0f), Value(U, 1.1f, 6.1f), notUsed, 0.25f,
2731 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(modVecScalar))
2732 << operInfoFunc(modName, modOp, UV, Value(UV, 0.0f, 24.0f), Value(U, 1.1f, 11.1f), notUsed, 0.1f,
2733 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(modVecScalar));
2734
2735 if (isNormalOp)
2736 binaryOpGroup << operInfoFunc(modName, modOp, IV, Value(I, 0.0f, 6.0f), Value(IV, 1.1f, 6.1f), notUsed,
2737 0.25f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(modScalarVec))
2738 << operInfoFunc(modName, modOp, IV, Value(I, 0.0f, 6.0f), Value(IV, 1.1f, 11.1f), notUsed,
2739 0.1f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(modScalarVec))
2740 << operInfoFunc(modName, modOp, UV, Value(U, 0.0f, 6.0f), Value(UV, 1.1f, 6.1f), notUsed,
2741 0.25f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(modScalarVec))
2742 << operInfoFunc(modName, modOp, UV, Value(U, 0.0f, 24.0f), Value(UV, 1.1f, 11.1f), notUsed,
2743 0.1f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(modScalarVec));
2744
2745 // The bitwise and operator.
2746
2747 binaryOpGroup << operInfoFunc(andName, andOp, IGT, Value(IGT, -16.0f, 16.0f), Value(IGT, -16.0f, 16.0f),
2748 notUsed, 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(bitwiseAnd))
2749 << operInfoFunc(andName, andOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2750 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseAnd))
2751 << operInfoFunc(andName, andOp, UGT, Value(UGT, 0.0f, 32.0f), Value(UGT, 0.0f, 32.0f), notUsed,
2752 0.03f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(bitwiseAnd))
2753 << operInfoFunc(andName, andOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2754 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseAnd))
2755 << operInfoFunc(andName, andOp, IV, Value(IV, -16.0f, 16.0f), Value(I, -16.0f, 16.0f), notUsed,
2756 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(bitwiseAndVecScalar))
2757 << operInfoFunc(andName, andOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2758 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseAndVecScalar))
2759 << operInfoFunc(andName, andOp, UV, Value(UV, 0.0f, 32.0f), Value(U, 0.0f, 32.0f), notUsed, 0.03f,
2760 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(bitwiseAndVecScalar))
2761 << operInfoFunc(andName, andOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2762 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseAndVecScalar));
2763
2764 if (isNormalOp)
2765 binaryOpGroup << operInfoFunc(andName, andOp, IV, Value(I, -16.0f, 16.0f), Value(IV, -16.0f, 16.0f),
2766 notUsed, 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP,
2767 INT_VEC_FUNCS(bitwiseAndScalarVec))
2768 << operInfoFunc(andName, andOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2769 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseAndScalarVec))
2770 << operInfoFunc(andName, andOp, UV, Value(U, 0.0f, 32.0f), Value(UV, 0.0f, 32.0f), notUsed,
2771 0.03f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(bitwiseAndScalarVec))
2772 << operInfoFunc(andName, andOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2773 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseAndScalarVec));
2774
2775 // The bitwise or operator.
2776
2777 binaryOpGroup << operInfoFunc(orName, orOp, IGT, Value(IGT, -16.0f, 16.0f), Value(IGT, -16.0f, 16.0f), notUsed,
2778 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(bitwiseOr))
2779 << operInfoFunc(orName, orOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2780 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseOr))
2781 << operInfoFunc(orName, orOp, UGT, Value(UGT, 0.0f, 32.0f), Value(UGT, 0.0f, 32.0f), notUsed,
2782 0.03f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(bitwiseOr))
2783 << operInfoFunc(orName, orOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2784 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseOr))
2785 << operInfoFunc(orName, orOp, IV, Value(IV, -16.0f, 16.0f), Value(I, -16.0f, 16.0f), notUsed,
2786 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(bitwiseOrVecScalar))
2787 << operInfoFunc(orName, orOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed, 4e-10f,
2788 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseOrVecScalar))
2789 << operInfoFunc(orName, orOp, UV, Value(UV, 0.0f, 32.0f), Value(U, 0.0f, 32.0f), notUsed, 0.03f,
2790 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(bitwiseOrVecScalar))
2791 << operInfoFunc(orName, orOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2792 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseOrVecScalar));
2793
2794 if (isNormalOp)
2795 binaryOpGroup << operInfoFunc(orName, orOp, IV, Value(I, -16.0f, 16.0f), Value(IV, -16.0f, 16.0f), notUsed,
2796 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(bitwiseOrScalarVec))
2797 << operInfoFunc(orName, orOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2798 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseOrScalarVec))
2799 << operInfoFunc(orName, orOp, UV, Value(U, 0.0f, 32.0f), Value(UV, 0.0f, 32.0f), notUsed,
2800 0.03f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(bitwiseOrScalarVec))
2801 << operInfoFunc(orName, orOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2802 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseOrScalarVec));
2803
2804 // The bitwise xor operator.
2805
2806 binaryOpGroup << operInfoFunc(xorName, xorOp, IGT, Value(IGT, -16.0f, 16.0f), Value(IGT, -16.0f, 16.0f),
2807 notUsed, 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_GENTYPE_FUNCS(bitwiseXor))
2808 << operInfoFunc(xorName, xorOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2809 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseXor))
2810 << operInfoFunc(xorName, xorOp, UGT, Value(UGT, 0.0f, 32.0f), Value(UGT, 0.0f, 32.0f), notUsed,
2811 0.03f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_GENTYPE_FUNCS(bitwiseXor))
2812 << operInfoFunc(xorName, xorOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2813 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseXor))
2814 << operInfoFunc(xorName, xorOp, IV, Value(IV, -16.0f, 16.0f), Value(I, -16.0f, 16.0f), notUsed,
2815 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP, INT_VEC_FUNCS(bitwiseXorVecScalar))
2816 << operInfoFunc(xorName, xorOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2817 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseXorVecScalar))
2818 << operInfoFunc(xorName, xorOp, UV, Value(UV, 0.0f, 32.0f), Value(U, 0.0f, 32.0f), notUsed, 0.03f,
2819 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(bitwiseXorVecScalar))
2820 << operInfoFunc(xorName, xorOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2821 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseXorVecScalar));
2822
2823 if (isNormalOp)
2824 binaryOpGroup << operInfoFunc(xorName, xorOp, IV, Value(I, -16.0f, 16.0f), Value(IV, -16.0f, 16.0f),
2825 notUsed, 0.03f, 0.5f, PRECMASK_LOWP_MEDIUMP,
2826 INT_VEC_FUNCS(bitwiseXorScalarVec))
2827 << operInfoFunc(xorName, xorOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2828 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseXorScalarVec))
2829 << operInfoFunc(xorName, xorOp, UV, Value(U, 0.0f, 32.0f), Value(UV, 0.0f, 32.0f), notUsed,
2830 0.03f, 0.0f, PRECMASK_LOWP_MEDIUMP, UINT_VEC_FUNCS(bitwiseXorScalarVec))
2831 << operInfoFunc(xorName, xorOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2832 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseXorScalarVec));
2833
2834 // The left shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
2835
2836 for (int isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++)
2837 {
2838 ValueType gType = isSignedAmount == 0 ? UGT : IGT;
2839 ValueType sType = isSignedAmount == 0 ? U : I;
2840 binaryOpGroup << operInfoFunc(leftShiftName, leftShiftOp, IGT, Value(IGT, -7.0f, 7.0f),
2841 Value(gType, 0.0f, 4.0f), notUsed, 4e-3f, 0.5f, PRECMASK_LOWP_MEDIUMP,
2842 INT_GENTYPE_FUNCS(leftShift))
2843 << operInfoFunc(leftShiftName, leftShiftOp, IGT, Value(IGT, -7.0f, 7.0f),
2844 Value(gType, 0.0f, 27.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2845 INT_GENTYPE_FUNCS(leftShift))
2846 << operInfoFunc(leftShiftName, leftShiftOp, UGT, Value(UGT, 0.0f, 7.0f),
2847 Value(gType, 0.0f, 5.0f), notUsed, 4e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP,
2848 UINT_GENTYPE_FUNCS(leftShift))
2849 << operInfoFunc(leftShiftName, leftShiftOp, UGT, Value(UGT, 0.0f, 7.0f),
2850 Value(gType, 0.0f, 28.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2851 UINT_GENTYPE_FUNCS(leftShift))
2852 << operInfoFunc(leftShiftName, leftShiftOp, IV, Value(IV, -7.0f, 7.0f),
2853 Value(sType, 0.0f, 4.0f), notUsed, 4e-3f, 0.5f, PRECMASK_LOWP_MEDIUMP,
2854 INT_VEC_FUNCS(leftShiftVecScalar))
2855 << operInfoFunc(leftShiftName, leftShiftOp, IV, Value(IV, -7.0f, 7.0f),
2856 Value(sType, 0.0f, 27.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2857 INT_VEC_FUNCS(leftShiftVecScalar))
2858 << operInfoFunc(leftShiftName, leftShiftOp, UV, Value(UV, 0.0f, 7.0f),
2859 Value(sType, 0.0f, 5.0f), notUsed, 4e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP,
2860 UINT_VEC_FUNCS(leftShiftVecScalar))
2861 << operInfoFunc(leftShiftName, leftShiftOp, UV, Value(UV, 0.0f, 7.0f),
2862 Value(sType, 0.0f, 28.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2863 UINT_VEC_FUNCS(leftShiftVecScalar));
2864 }
2865
2866 // The right shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
2867
2868 for (int isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++)
2869 {
2870 ValueType gType = isSignedAmount == 0 ? UGT : IGT;
2871 ValueType sType = isSignedAmount == 0 ? U : I;
2872 binaryOpGroup << operInfoFunc(rightShiftName, rightShiftOp, IGT, Value(IGT, -127.0f, 127.0f),
2873 Value(gType, 0.0f, 8.0f), notUsed, 4e-3f, 0.5f, PRECMASK_LOWP_MEDIUMP,
2874 INT_GENTYPE_FUNCS(rightShift))
2875 << operInfoFunc(rightShiftName, rightShiftOp, IGT, Value(IGT, -2e9f, 2e9f),
2876 Value(gType, 0.0f, 31.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2877 INT_GENTYPE_FUNCS(rightShift))
2878 << operInfoFunc(rightShiftName, rightShiftOp, UGT, Value(UGT, 0.0f, 255.0f),
2879 Value(gType, 0.0f, 8.0f), notUsed, 4e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP,
2880 UINT_GENTYPE_FUNCS(rightShift))
2881 << operInfoFunc(rightShiftName, rightShiftOp, UGT, Value(UGT, 0.0f, 4e9f),
2882 Value(gType, 0.0f, 31.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2883 UINT_GENTYPE_FUNCS(rightShift))
2884 << operInfoFunc(rightShiftName, rightShiftOp, IV, Value(IV, -127.0f, 127.0f),
2885 Value(sType, 0.0f, 8.0f), notUsed, 4e-3f, 0.5f, PRECMASK_LOWP_MEDIUMP,
2886 INT_VEC_FUNCS(rightShiftVecScalar))
2887 << operInfoFunc(rightShiftName, rightShiftOp, IV, Value(IV, -2e9f, 2e9f),
2888 Value(sType, 0.0f, 31.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2889 INT_VEC_FUNCS(rightShiftVecScalar))
2890 << operInfoFunc(rightShiftName, rightShiftOp, UV, Value(UV, 0.0f, 255.0f),
2891 Value(sType, 0.0f, 8.0f), notUsed, 4e-3f, 0.0f, PRECMASK_LOWP_MEDIUMP,
2892 UINT_VEC_FUNCS(rightShiftVecScalar))
2893 << operInfoFunc(rightShiftName, rightShiftOp, UV, Value(UV, 0.0f, 4e9f),
2894 Value(sType, 0.0f, 31.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2895 UINT_VEC_FUNCS(rightShiftVecScalar));
2896 }
2897 }
2898
2899 // Rest of binary operators.
2900
2901 binaryOpGroup
2902 // Scalar relational operators.
2903 << BuiltinOperInfo("less", "<", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2904 PRECMASK_ALL, eval_lessThan_float, DE_NULL, DE_NULL, DE_NULL)
2905 << BuiltinOperInfo("less", "<", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
2906 PRECMASK_ALL, eval_lessThan_int, DE_NULL, DE_NULL, DE_NULL)
2907 << BuiltinOperInfo("less", "<", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f, 0.0f,
2908 PRECMASK_ALL, eval_lessThan_uint, DE_NULL, DE_NULL, DE_NULL)
2909 << BuiltinOperInfo("less_or_equal", "<=", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2910 PRECMASK_ALL, eval_lessThanEqual_float, DE_NULL, DE_NULL, DE_NULL)
2911 << BuiltinOperInfo("less_or_equal", "<=", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
2912 PRECMASK_ALL, eval_lessThanEqual_int, DE_NULL, DE_NULL, DE_NULL)
2913 << BuiltinOperInfo("less_or_equal", "<=", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f, 0.0f,
2914 PRECMASK_ALL, eval_lessThanEqual_uint, DE_NULL, DE_NULL, DE_NULL)
2915 << BuiltinOperInfo("greater", ">", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2916 PRECMASK_ALL, eval_greaterThan_float, DE_NULL, DE_NULL, DE_NULL)
2917 << BuiltinOperInfo("greater", ">", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
2918 PRECMASK_ALL, eval_greaterThan_int, DE_NULL, DE_NULL, DE_NULL)
2919 << BuiltinOperInfo("greater", ">", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f, 0.0f,
2920 PRECMASK_ALL, eval_greaterThan_uint, DE_NULL, DE_NULL, DE_NULL)
2921 << BuiltinOperInfo("greater_or_equal", ">=", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2922 0.0f, PRECMASK_ALL, eval_greaterThanEqual_float, DE_NULL, DE_NULL, DE_NULL)
2923 << BuiltinOperInfo("greater_or_equal", ">=", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f,
2924 0.0f, PRECMASK_ALL, eval_greaterThanEqual_int, DE_NULL, DE_NULL, DE_NULL)
2925 << BuiltinOperInfo("greater_or_equal", ">=", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f,
2926 0.0f, PRECMASK_ALL, eval_greaterThanEqual_uint, DE_NULL, DE_NULL, DE_NULL)
2927
2928 // Equality comparison operators.
2929 << BuiltinOperInfo("equal", "==", B, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2930 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(allEqual))
2931 << BuiltinOperInfo("equal", "==", B, Value(IGT, -5.5f, 4.7f), Value(IGT, -2.1f, 0.1f), notUsed, 1.0f, 0.0f,
2932 PRECMASK_ALL, INT_GENTYPE_FUNCS(allEqual))
2933 << BuiltinOperInfo("equal", "==", B, Value(UGT, 0.0f, 8.0f), Value(UGT, 3.5f, 4.5f), notUsed, 1.0f, 0.0f,
2934 PRECMASK_ALL, UINT_GENTYPE_FUNCS(allEqual))
2935 << BuiltinOperInfo("equal", "==", B, Value(BGT, -2.1f, 2.1f), Value(BGT, -1.1f, 3.0f), notUsed, 1.0f, 0.0f,
2936 PRECMASK_NA, BOOL_GENTYPE_FUNCS(allEqual))
2937 << BuiltinOperInfo("not_equal", "!=", B, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2938 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(anyNotEqual))
2939 << BuiltinOperInfo("not_equal", "!=", B, Value(IGT, -5.5f, 4.7f), Value(IGT, -2.1f, 0.1f), notUsed, 1.0f, 0.0f,
2940 PRECMASK_ALL, INT_GENTYPE_FUNCS(anyNotEqual))
2941 << BuiltinOperInfo("not_equal", "!=", B, Value(UGT, 0.0f, 8.0f), Value(UGT, 3.5f, 4.5f), notUsed, 1.0f, 0.0f,
2942 PRECMASK_ALL, UINT_GENTYPE_FUNCS(anyNotEqual))
2943 << BuiltinOperInfo("not_equal", "!=", B, Value(BGT, -2.1f, 2.1f), Value(BGT, -1.1f, 3.0f), notUsed, 1.0f, 0.0f,
2944 PRECMASK_NA, BOOL_GENTYPE_FUNCS(anyNotEqual))
2945
2946 // Logical operators.
2947 << BuiltinOperInfo("logical_and", "&&", B, Value(B, -1.0f, 1.0f), Value(B, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2948 PRECMASK_NA, BOOL_FUNCS(logicalAnd))
2949 << BuiltinOperInfo("logical_or", "||", B, Value(B, -1.0f, 1.0f), Value(B, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2950 PRECMASK_NA, BOOL_FUNCS(logicalOr))
2951 << BuiltinOperInfo("logical_xor", "^^", B, Value(B, -1.0f, 1.0f), Value(B, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2952 PRECMASK_NA, BOOL_FUNCS(logicalXor));
2953
2954 funcInfoGroups.push_back(binaryOpGroup);
2955
2956 // 8.1 Angle and Trigonometry Functions.
2957 funcInfoGroups.push_back(BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.")
2958 << BuiltinFuncInfo("radians", "radians", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed,
2959 25.0f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(radians))
2960 << BuiltinFuncInfo("degrees", "degrees", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed,
2961 0.04f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(degrees))
2962 << BuiltinFuncInfo("sin", "sin", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f, 0.5f,
2963 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(sin))
2964 << BuiltinFuncInfo("sin", "sin", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.5f, 0.5f,
2965 PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(sin))
2966 << BuiltinFuncInfo("cos", "cos", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f, 0.5f,
2967 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(cos))
2968 << BuiltinFuncInfo("cos", "cos", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.5f, 0.5f,
2969 PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(cos))
2970 << BuiltinFuncInfo("tan", "tan", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f, 0.5f,
2971 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(tan))
2972 << BuiltinFuncInfo("tan", "tan", GT, Value(GT, -1.5f, 5.5f), notUsed, notUsed, 0.5f, 0.5f,
2973 PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(tan))
2974 << BuiltinFuncInfo("asin", "asin", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 1.0f,
2975 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(asin))
2976 << BuiltinFuncInfo("acos", "acos", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 1.0f,
2977 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(acos))
2978 << BuiltinFuncInfo("atan", "atan", GT, Value(GT, -4.0f, 4.0f), notUsed, notUsed, 0.5f,
2979 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(atan))
2980 << BuiltinFuncInfo("atan2", "atan", GT, Value(GT, -4.0f, 4.0f), Value(GT, 0.5f, 2.0f),
2981 notUsed, 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(atan2))
2982 << BuiltinFuncInfo("sinh", "sinh", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f,
2983 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(sinh))
2984 << BuiltinFuncInfo("sinh", "sinh", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.5f,
2985 0.5f, PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(sinh))
2986 << BuiltinFuncInfo("cosh", "cosh", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f,
2987 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(cosh))
2988 << BuiltinFuncInfo("cosh", "cosh", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.5f,
2989 0.5f, PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(cosh))
2990 << BuiltinFuncInfo("tanh", "tanh", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f,
2991 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(tanh))
2992 << BuiltinFuncInfo("tanh", "tanh", GT, Value(GT, -1.5f, 5.5f), notUsed, notUsed, 0.5f,
2993 0.5f, PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(tanh))
2994 << BuiltinFuncInfo("asinh", "asinh", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 1.0f,
2995 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(asinh))
2996 << BuiltinFuncInfo("acosh", "acosh", GT, Value(GT, 1.0f, 2.2f), notUsed, notUsed, 1.0f,
2997 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(acosh))
2998 << BuiltinFuncInfo("atanh", "atanh", GT, Value(GT, -0.99f, 0.99f), notUsed, notUsed, 1.0f,
2999 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(atanh)));
3000
3001 // 8.2 Exponential Functions.
3002 funcInfoGroups.push_back(BuiltinFuncGroup("exponential", "Exponential function tests")
3003 << BuiltinFuncInfo("pow", "pow", GT, Value(GT, 0.1f, 8.0f), Value(GT, -4.0f, 2.0f),
3004 notUsed, 1.0f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(pow))
3005 << BuiltinFuncInfo("exp", "exp", GT, Value(GT, -6.0f, 3.0f), notUsed, notUsed, 0.5f, 0.0f,
3006 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(exp))
3007 << BuiltinFuncInfo("log", "log", GT, Value(GT, 0.1f, 10.0f), notUsed, notUsed, 0.5f, 0.3f,
3008 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(log))
3009 << BuiltinFuncInfo("exp2", "exp2", GT, Value(GT, -7.0f, 2.0f), notUsed, notUsed, 1.0f,
3010 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(exp2))
3011 << BuiltinFuncInfo("log2", "log2", GT, Value(GT, 0.1f, 10.0f), notUsed, notUsed, 1.0f,
3012 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(log2))
3013 << BuiltinFuncInfo("sqrt", "sqrt", GT, Value(GT, 0.0f, 10.0f), notUsed, notUsed, 0.3f,
3014 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(sqrt))
3015 << BuiltinFuncInfo("inversesqrt", "inversesqrt", GT, Value(GT, 0.5f, 10.0f), notUsed,
3016 notUsed, 1.0f, 0.0f, PRECMASK_MEDIUMP_HIGHP,
3017 FLOAT_GENTYPE_FUNCS(inverseSqrt)));
3018
3019 // 8.3 Common Functions.
3020 funcInfoGroups.push_back(
3021 BuiltinFuncGroup("common_functions", "Common function tests.")
3022 << BuiltinFuncInfo("abs", "abs", GT, Value(GT, -2.0f, 2.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL,
3023 FLOAT_GENTYPE_FUNCS(abs))
3024 << BuiltinFuncInfo("sign", "sign", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.3f, 0.5f, PRECMASK_ALL,
3025 FLOAT_GENTYPE_FUNCS(sign))
3026 << BuiltinFuncInfo("floor", "floor", GT, Value(GT, -2.5f, 2.5f), notUsed, notUsed, 0.2f, 0.7f, PRECMASK_ALL,
3027 FLOAT_GENTYPE_FUNCS(floor))
3028 << BuiltinFuncInfo("trunc", "trunc", GT, Value(GT, -2.5f, 2.5f), notUsed, notUsed, 0.2f, 0.7f, PRECMASK_ALL,
3029 FLOAT_GENTYPE_FUNCS(trunc))
3030 << BuiltinFuncInfo("round", "round", GT, Value(GT, -2.5f, 2.5f), notUsed, notUsed, 0.2f, 0.7f, PRECMASK_ALL,
3031 FLOAT_GENTYPE_FUNCS(roundToEven))
3032 << BuiltinFuncInfo("roundEven", "roundEven", GT, Value(GT, -2.5f, 2.5f), notUsed, notUsed, 0.2f, 0.7f,
3033 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(roundToEven))
3034 << BuiltinFuncInfo("ceil", "ceil", GT, Value(GT, -2.5f, 2.5f), notUsed, notUsed, 0.2f, 0.5f, PRECMASK_ALL,
3035 FLOAT_GENTYPE_FUNCS(ceil))
3036 << BuiltinFuncInfo("fract", "fract", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.8f, 0.1f, PRECMASK_ALL,
3037 FLOAT_GENTYPE_FUNCS(fract))
3038 << BuiltinFuncInfo("mod", "mod", GT, Value(GT, -2.0f, 2.0f), Value(GT, 0.9f, 6.0f), notUsed, 0.5f, 0.5f,
3039 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(mod))
3040 << BuiltinFuncInfo("mod", "mod", GT, Value(FV, -2.0f, 2.0f), Value(F, 0.9f, 6.0f), notUsed, 0.5f, 0.5f,
3041 PRECMASK_MEDIUMP_HIGHP, FLOAT_VEC_FUNCS(modVecScalar))
3042 << BuiltinFuncInfo("min", "min", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.5f, 0.5f,
3043 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(min))
3044 << BuiltinFuncInfo("min", "min", GT, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.5f, 0.5f,
3045 PRECMASK_ALL, FLOAT_VEC_FUNCS(minVecScalar))
3046 << BuiltinFuncInfo("min", "min", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
3047 PRECMASK_ALL, INT_GENTYPE_FUNCS(min))
3048 << BuiltinFuncInfo("min", "min", IGT, Value(IV, -4.0f, 4.0f), Value(I, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
3049 PRECMASK_ALL, INT_VEC_FUNCS(minVecScalar))
3050 << BuiltinFuncInfo("min", "min", UGT, Value(UGT, 0.0f, 8.0f), Value(UGT, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
3051 PRECMASK_ALL, UINT_GENTYPE_FUNCS(min))
3052 << BuiltinFuncInfo("min", "min", UGT, Value(UV, 0.0f, 8.0f), Value(U, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
3053 PRECMASK_ALL, UINT_VEC_FUNCS(minVecScalar))
3054 << BuiltinFuncInfo("max", "max", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.5f, 0.5f,
3055 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(max))
3056 << BuiltinFuncInfo("max", "max", GT, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.5f, 0.5f,
3057 PRECMASK_ALL, FLOAT_VEC_FUNCS(maxVecScalar))
3058 << BuiltinFuncInfo("max", "max", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
3059 PRECMASK_ALL, INT_GENTYPE_FUNCS(max))
3060 << BuiltinFuncInfo("max", "max", IGT, Value(IV, -4.0f, 4.0f), Value(I, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
3061 PRECMASK_ALL, INT_VEC_FUNCS(maxVecScalar))
3062 << BuiltinFuncInfo("max", "max", UGT, Value(UGT, 0.0f, 8.0f), Value(UGT, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
3063 PRECMASK_ALL, UINT_GENTYPE_FUNCS(max))
3064 << BuiltinFuncInfo("max", "max", UGT, Value(UV, 0.0f, 8.0f), Value(U, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
3065 PRECMASK_ALL, UINT_VEC_FUNCS(maxVecScalar))
3066 << BuiltinFuncInfo("clamp", "clamp", GT, Value(GT, -1.0f, 1.0f), Value(GT, -0.5f, 0.5f), Value(GT, 0.5f, 1.0f),
3067 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(clamp))
3068 << BuiltinFuncInfo("clamp", "clamp", GT, Value(FV, -1.0f, 1.0f), Value(F, -0.5f, 0.5f), Value(F, 0.5f, 1.0f),
3069 0.5f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(clampVecScalarScalar))
3070 << BuiltinFuncInfo("clamp", "clamp", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -2.0f, 2.0f),
3071 Value(IGT, 2.0f, 4.0f), 0.125f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(clamp))
3072 << BuiltinFuncInfo("clamp", "clamp", IGT, Value(IV, -4.0f, 4.0f), Value(I, -2.0f, 2.0f), Value(I, 2.0f, 4.0f),
3073 0.125f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(clampVecScalarScalar))
3074 << BuiltinFuncInfo("clamp", "clamp", UGT, Value(UGT, 0.0f, 8.0f), Value(UGT, 2.0f, 6.0f),
3075 Value(UGT, 6.0f, 8.0f), 0.125f, 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(clamp))
3076 << BuiltinFuncInfo("clamp", "clamp", UGT, Value(UV, 0.0f, 8.0f), Value(U, 2.0f, 6.0f), Value(U, 6.0f, 8.0f),
3077 0.125f, 0.0f, PRECMASK_ALL, UINT_VEC_FUNCS(clampVecScalarScalar))
3078 << BuiltinFuncInfo("mix", "mix", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), Value(GT, 0.0f, 1.0f),
3079 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(mix))
3080 << BuiltinFuncInfo("mix", "mix", GT, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), Value(F, 0.0f, 1.0f), 0.5f,
3081 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mixVecVecScalar))
3082 << BuiltinFuncInfo("step", "step", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 0.0f), notUsed, 0.5f, 0.25f,
3083 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(step))
3084 << BuiltinFuncInfo("step", "step", GT, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 0.0f), notUsed, 0.5f, 0.25f,
3085 PRECMASK_ALL, FLOAT_VEC_FUNCS(stepScalarVec))
3086 << BuiltinFuncInfo("smoothstep", "smoothstep", GT, Value(GT, -0.5f, 0.0f), Value(GT, 0.1f, 1.0f),
3087 Value(GT, -1.0f, 1.0f), 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(smoothStep))
3088 << BuiltinFuncInfo("smoothstep", "smoothstep", GT, Value(F, -0.5f, 0.0f), Value(F, 0.1f, 1.0f),
3089 Value(FV, -1.0f, 1.0f), 0.5f, 0.5f, PRECMASK_ALL,
3090 FLOAT_VEC_FUNCS(smoothStepScalarScalarVec)));
3091
3092 // 8.4 Geometric Functions.
3093 funcInfoGroups.push_back(
3094 BuiltinFuncGroup("geometric", "Geometric function tests.")
3095 << BuiltinFuncInfo("length", "length", F, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f,
3096 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(length))
3097 << BuiltinFuncInfo("distance", "distance", F, Value(GT, -5.0f, 5.0f), Value(GT, -5.0f, 5.0f), notUsed, 0.1f,
3098 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(distance))
3099 << BuiltinFuncInfo("dot", "dot", F, Value(GT, -5.0f, 5.0f), Value(GT, -5.0f, 5.0f), notUsed, 0.1f, 0.5f,
3100 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(dot))
3101 << BuiltinFuncInfo("cross", "cross", V3, Value(GT, -5.0f, 5.0f), Value(GT, -5.0f, 5.0f), notUsed, 0.1f, 0.5f,
3102 PRECMASK_MEDIUMP_HIGHP, DE_NULL, DE_NULL, eval_cross_vec3, DE_NULL)
3103 << BuiltinFuncInfo("normalize", "normalize", GT, Value(GT, 0.1f, 4.0f), notUsed, notUsed, 0.5f, 0.5f,
3104 PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(normalize))
3105 << BuiltinFuncInfo("faceforward", "faceforward", GT, Value(GT, -5.0f, 5.0f), Value(GT, -5.0f, 5.0f),
3106 Value(GT, -1.0f, 1.0f), 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(faceForward))
3107 << BuiltinFuncInfo("reflect", "reflect", GT, Value(GT, -0.8f, -0.5f), Value(GT, 0.5f, 0.8f), notUsed, 0.5f,
3108 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(reflect))
3109 << BuiltinFuncInfo("refract", "refract", GT, Value(GT, -0.8f, 1.2f), Value(GT, -1.1f, 0.5f),
3110 Value(F, 0.2f, 1.5f), 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(refract)));
3111
3112 // 8.5 Matrix Functions.
3113 // separate matrix tests?
3114 // funcInfoGroups.push_back(
3115 // BuiltinFuncGroup("matrix", "Matrix function tests.")
3116 // << BuiltinFuncInfo("matrixCompMult", "matrixCompMult", M, ... )
3117 // );
3118
3119 // 8.6 Vector Relational Functions.
3120 funcInfoGroups.push_back(
3121 BuiltinFuncGroup("float_compare", "Floating point comparison tests.")
3122 << BuiltinFuncInfo("lessThan", "lessThan", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f,
3123 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(lessThan))
3124 << BuiltinFuncInfo("lessThanEqual", "lessThanEqual", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f),
3125 notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(lessThanEqual))
3126 << BuiltinFuncInfo("greaterThan", "greaterThan", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
3127 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(greaterThan))
3128 << BuiltinFuncInfo("greaterThanEqual", "greaterThanEqual", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f),
3129 notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(greaterThanEqual))
3130 << BuiltinFuncInfo("equal", "equal", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
3131 PRECMASK_ALL, FLOAT_VEC_FUNCS(equal))
3132 << BuiltinFuncInfo("notEqual", "notEqual", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f,
3133 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(notEqual)));
3134
3135 funcInfoGroups.push_back(
3136 BuiltinFuncGroup("int_compare", "Integer comparison tests.")
3137 << BuiltinFuncInfo("lessThan", "lessThan", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed, 1.0f,
3138 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(lessThan))
3139 << BuiltinFuncInfo("lessThanEqual", "lessThanEqual", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f),
3140 notUsed, 1.0f, 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(lessThanEqual))
3141 << BuiltinFuncInfo("greaterThan", "greaterThan", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed,
3142 1.0f, 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(greaterThan))
3143 << BuiltinFuncInfo("greaterThanEqual", "greaterThanEqual", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f),
3144 notUsed, 1.0f, 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(greaterThanEqual))
3145 << BuiltinFuncInfo("equal", "equal", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
3146 PRECMASK_ALL, INT_VEC_FUNCS(equal))
3147 << BuiltinFuncInfo("notEqual", "notEqual", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed, 1.0f,
3148 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(notEqual)));
3149
3150 funcInfoGroups.push_back(BuiltinFuncGroup("bool_compare", "Boolean comparison tests.")
3151 << BuiltinFuncInfo("equal", "equal", BV, Value(BV, -5.2f, 4.9f), Value(BV, -5.0f, 5.0f),
3152 notUsed, 1.0f, 0.0f, PRECMASK_NA, BOOL_VEC_FUNCS(equal))
3153 << BuiltinFuncInfo("notEqual", "notEqual", BV, Value(BV, -5.2f, 4.9f),
3154 Value(BV, -5.0f, 5.0f), notUsed, 1.0f, 0.0f, PRECMASK_NA,
3155 BOOL_VEC_FUNCS(notEqual))
3156 << BuiltinFuncInfo("any", "any", B, Value(BV, -1.0f, 0.3f), notUsed, notUsed, 1.0f, 0.0f,
3157 PRECMASK_NA, BOOL_VEC_FUNCS(any))
3158 << BuiltinFuncInfo("all", "all", B, Value(BV, -0.3f, 1.0f), notUsed, notUsed, 1.0f, 0.0f,
3159 PRECMASK_NA, BOOL_VEC_FUNCS(all))
3160 << BuiltinFuncInfo("not", "not", BV, Value(BV, -1.0f, 1.0f), notUsed, notUsed, 1.0f, 0.0f,
3161 PRECMASK_NA, BOOL_VEC_FUNCS(boolNot)));
3162
3163 static const ShaderType s_shaderTypes[] = {SHADERTYPE_VERTEX, SHADERTYPE_FRAGMENT};
3164
3165 static const DataType s_floatTypes[] = {TYPE_FLOAT, TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4};
3166
3167 static const DataType s_intTypes[] = {TYPE_INT, TYPE_INT_VEC2, TYPE_INT_VEC3, TYPE_INT_VEC4};
3168
3169 static const DataType s_uintTypes[] = {TYPE_UINT, TYPE_UINT_VEC2, TYPE_UINT_VEC3, TYPE_UINT_VEC4};
3170
3171 static const DataType s_boolTypes[] = {TYPE_BOOL, TYPE_BOOL_VEC2, TYPE_BOOL_VEC3, TYPE_BOOL_VEC4};
3172
3173 for (int outerGroupNdx = 0; outerGroupNdx < (int)funcInfoGroups.size(); outerGroupNdx++)
3174 {
3175 // Create outer group.
3176 const BuiltinFuncGroup &outerGroupInfo = funcInfoGroups[outerGroupNdx];
3177 TestCaseGroup *outerGroup = new TestCaseGroup(m_context, outerGroupInfo.name, outerGroupInfo.description);
3178 addChild(outerGroup);
3179
3180 // Only create new group if name differs from previous one.
3181 TestCaseGroup *innerGroup = DE_NULL;
3182
3183 for (int funcInfoNdx = 0; funcInfoNdx < (int)outerGroupInfo.funcInfos.size(); funcInfoNdx++)
3184 {
3185 const BuiltinFuncInfo &funcInfo = outerGroupInfo.funcInfos[funcInfoNdx];
3186 const char *shaderFuncName = funcInfo.shaderFuncName;
3187 bool isBoolCase = (funcInfo.precisionMask == PRECMASK_NA);
3188 bool isBoolOut = (funcInfo.outValue & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0;
3189 bool isIntOut = (funcInfo.outValue & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0;
3190 bool isUintOut = (funcInfo.outValue & (VALUE_UINT | VALUE_UINT_VEC | VALUE_UINT_GENTYPE)) != 0;
3191 bool isFloatOut = !isBoolOut && !isIntOut && !isUintOut;
3192
3193 if (!innerGroup || (string(innerGroup->getName()) != funcInfo.caseName))
3194 {
3195 string groupDesc = string("Built-in function ") + shaderFuncName + "() tests.";
3196 innerGroup = new TestCaseGroup(m_context, funcInfo.caseName, groupDesc.c_str());
3197 outerGroup->addChild(innerGroup);
3198 }
3199
3200 for (int inScalarSize = 1; inScalarSize <= 4; inScalarSize++)
3201 {
3202 int outScalarSize = ((funcInfo.outValue == VALUE_FLOAT) || (funcInfo.outValue == VALUE_BOOL)) ?
3203 1 :
3204 inScalarSize; // \todo [petri] Int.
3205 DataType outDataType = isFloatOut ? s_floatTypes[outScalarSize - 1] :
3206 isIntOut ? s_intTypes[outScalarSize - 1] :
3207 isUintOut ? s_uintTypes[outScalarSize - 1] :
3208 isBoolOut ? s_boolTypes[outScalarSize - 1] :
3209 TYPE_LAST;
3210
3211 ShaderEvalFunc evalFunc = DE_NULL;
3212 switch (inScalarSize)
3213 {
3214 case 1:
3215 evalFunc = funcInfo.evalFuncScalar;
3216 break;
3217 case 2:
3218 evalFunc = funcInfo.evalFuncVec2;
3219 break;
3220 case 3:
3221 evalFunc = funcInfo.evalFuncVec3;
3222 break;
3223 case 4:
3224 evalFunc = funcInfo.evalFuncVec4;
3225 break;
3226 default:
3227 DE_ASSERT(false);
3228 }
3229 // Skip if no valid eval func.
3230 // \todo [petri] Better check for V3 only etc. cases?
3231 if (evalFunc == DE_NULL)
3232 continue;
3233
3234 for (int precision = 0; precision < PRECISION_LAST; precision++)
3235 {
3236 if ((funcInfo.precisionMask & (1 << precision)) ||
3237 (funcInfo.precisionMask == PRECMASK_NA &&
3238 precision == PRECISION_MEDIUMP)) // use mediump interpolators for booleans
3239 {
3240 const char *precisionStr = getPrecisionName((Precision)precision);
3241 string precisionPrefix = isBoolCase ? "" : (string(precisionStr) + "_");
3242
3243 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
3244 {
3245 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
3246 ShaderDataSpec shaderSpec;
3247 const char *shaderTypeName = getShaderTypeName(shaderType);
3248 bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX;
3249 bool isUnaryOp = (funcInfo.input1.valueType == VALUE_NONE);
3250
3251 // \note Data type names will be added to description and name in a following loop.
3252 string desc = string("Built-in function ") + shaderFuncName + "(";
3253 string name = precisionPrefix;
3254
3255 // Generate shader op.
3256 string shaderOp = "res = ";
3257
3258 // Setup shader data info.
3259 shaderSpec.numInputs = 0;
3260 shaderSpec.precision = isBoolCase ? PRECISION_LAST : (Precision)precision;
3261 shaderSpec.output = outDataType;
3262 shaderSpec.resultScale = funcInfo.resultScale;
3263 shaderSpec.resultBias = funcInfo.resultBias;
3264 shaderSpec.referenceScale = funcInfo.referenceScale;
3265 shaderSpec.referenceBias = funcInfo.referenceBias;
3266
3267 if (funcInfo.type == OPERATOR)
3268 {
3269 if (isUnaryOp && funcInfo.isUnaryPrefix)
3270 shaderOp += shaderFuncName;
3271 }
3272 else if (funcInfo.type == FUNCTION)
3273 shaderOp += string(shaderFuncName) + "(";
3274 else // SIDE_EFFECT_OPERATOR
3275 shaderOp += "in0;\n\t";
3276
3277 for (int inputNdx = 0; inputNdx < MAX_INPUTS; inputNdx++)
3278 {
3279 const Value &prevV = (inputNdx == 1) ? funcInfo.input0 :
3280 (inputNdx == 2) ? funcInfo.input1 :
3281 funcInfo.input2;
3282 const Value &v = (inputNdx == 0) ? funcInfo.input0 :
3283 (inputNdx == 1) ? funcInfo.input1 :
3284 funcInfo.input2;
3285
3286 if (v.valueType == VALUE_NONE)
3287 continue; // Skip unused input.
3288
3289 int prevInScalarSize = isScalarType(prevV.valueType) ? 1 : inScalarSize;
3290 DataType prevInDataType =
3291 isFloatType(prevV.valueType) ? s_floatTypes[prevInScalarSize - 1] :
3292 isIntType(prevV.valueType) ? s_intTypes[prevInScalarSize - 1] :
3293 isUintType(prevV.valueType) ? s_uintTypes[prevInScalarSize - 1] :
3294 isBoolType(prevV.valueType) ? s_boolTypes[prevInScalarSize - 1] :
3295 TYPE_LAST;
3296
3297 int curInScalarSize = isScalarType(v.valueType) ? 1 : inScalarSize;
3298 DataType curInDataType = isFloatType(v.valueType) ? s_floatTypes[curInScalarSize - 1] :
3299 isIntType(v.valueType) ? s_intTypes[curInScalarSize - 1] :
3300 isUintType(v.valueType) ? s_uintTypes[curInScalarSize - 1] :
3301 isBoolType(v.valueType) ? s_boolTypes[curInScalarSize - 1] :
3302 TYPE_LAST;
3303
3304 // Write input type(s) to case description and name.
3305
3306 if (inputNdx > 0)
3307 desc += ", ";
3308
3309 desc += getDataTypeName(curInDataType);
3310
3311 if (inputNdx == 0 ||
3312 prevInDataType !=
3313 curInDataType) // \note Only write input type to case name if different from previous input type (avoid overly long names).
3314 name += string("") + getDataTypeName(curInDataType) + "_";
3315
3316 // Generate op input source.
3317
3318 if (funcInfo.type == OPERATOR || funcInfo.type == FUNCTION)
3319 {
3320 if (inputNdx != 0)
3321 {
3322 if (funcInfo.type == OPERATOR && !isUnaryOp)
3323 shaderOp += " " + string(shaderFuncName) + " ";
3324 else
3325 shaderOp += ", ";
3326 }
3327
3328 shaderOp += "in" + de::toString(inputNdx);
3329
3330 if (funcInfo.type == OPERATOR && isUnaryOp && !funcInfo.isUnaryPrefix)
3331 shaderOp += string(shaderFuncName);
3332 }
3333 else
3334 {
3335 DE_ASSERT(funcInfo.type == SIDE_EFFECT_OPERATOR);
3336
3337 if (inputNdx != 0 || (isUnaryOp && funcInfo.isUnaryPrefix))
3338 shaderOp += string("") + (isUnaryOp ? "" : " ") + shaderFuncName +
3339 (isUnaryOp ? "" : " ");
3340
3341 shaderOp +=
3342 inputNdx == 0 ?
3343 "res" :
3344 "in" +
3345 de::toString(
3346 inputNdx); // \note in0 has already been assigned to res, so start from in1.
3347
3348 if (isUnaryOp && !funcInfo.isUnaryPrefix)
3349 shaderOp += shaderFuncName;
3350 }
3351
3352 // Fill in shader info.
3353 shaderSpec.inputs[shaderSpec.numInputs++] =
3354 ShaderValue(curInDataType, v.rangeMin, v.rangeMax);
3355 }
3356
3357 if (funcInfo.type == FUNCTION)
3358 shaderOp += ")";
3359
3360 shaderOp += ";";
3361
3362 desc += ").";
3363 name += shaderTypeName;
3364
3365 // Create the test case.
3366 innerGroup->addChild(new ShaderOperatorCase(m_context, name.c_str(), desc.c_str(),
3367 isVertexCase, evalFunc, shaderOp, shaderSpec));
3368 }
3369 }
3370 }
3371 }
3372 }
3373 }
3374
3375 // The ?: selection operator.
3376
3377 static const struct
3378 {
3379 DataType type; // The type of "Y" and "Z" operands in "X ? Y : Z" (X is always bool).
3380 ShaderEvalFunc evalFunc;
3381 } s_selectionInfo[] = {{TYPE_FLOAT, eval_selection_float}, {TYPE_FLOAT_VEC2, eval_selection_vec2},
3382 {TYPE_FLOAT_VEC3, eval_selection_vec3}, {TYPE_FLOAT_VEC4, eval_selection_vec4},
3383 {TYPE_INT, eval_selection_int}, {TYPE_INT_VEC2, eval_selection_ivec2},
3384 {TYPE_INT_VEC3, eval_selection_ivec3}, {TYPE_INT_VEC4, eval_selection_ivec4},
3385 {TYPE_UINT, eval_selection_uint}, {TYPE_UINT_VEC2, eval_selection_uvec2},
3386 {TYPE_UINT_VEC3, eval_selection_uvec3}, {TYPE_UINT_VEC4, eval_selection_uvec4},
3387 {TYPE_BOOL, eval_selection_bool}, {TYPE_BOOL_VEC2, eval_selection_bvec2},
3388 {TYPE_BOOL_VEC3, eval_selection_bvec3}, {TYPE_BOOL_VEC4, eval_selection_bvec4}};
3389
3390 TestCaseGroup *selectionGroup = new TestCaseGroup(m_context, "selection", "Selection operator tests");
3391 addChild(selectionGroup);
3392
3393 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_selectionInfo); typeNdx++)
3394 {
3395 DataType curType = s_selectionInfo[typeNdx].type;
3396 ShaderEvalFunc evalFunc = s_selectionInfo[typeNdx].evalFunc;
3397 bool isBoolCase = isDataTypeBoolOrBVec(curType);
3398 bool isFloatCase = isDataTypeFloatOrVec(curType);
3399 bool isIntCase = isDataTypeIntOrIVec(curType);
3400 bool isUintCase = isDataTypeUintOrUVec(curType);
3401 const char *dataTypeStr = getDataTypeName(curType);
3402
3403 DE_ASSERT(isBoolCase || isFloatCase || isIntCase || isUintCase);
3404 DE_UNREF(isIntCase);
3405
3406 for (int precision = 0; precision < (int)PRECISION_LAST; precision++)
3407 {
3408 if (isBoolCase && precision != PRECISION_MEDIUMP) // Use mediump interpolators for booleans.
3409 continue;
3410
3411 const char *precisionStr = getPrecisionName((Precision)precision);
3412 string precisionPrefix = isBoolCase ? "" : (string(precisionStr) + "_");
3413
3414 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
3415 {
3416 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
3417 ShaderDataSpec shaderSpec;
3418 const char *shaderTypeName = getShaderTypeName(shaderType);
3419 bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX;
3420
3421 string name = precisionPrefix + dataTypeStr + "_" + shaderTypeName;
3422
3423 shaderSpec.numInputs = 3;
3424 shaderSpec.precision = isBoolCase ? PRECISION_LAST : (Precision)precision;
3425 shaderSpec.output = curType;
3426 shaderSpec.resultScale = isBoolCase ? 1.0f : isFloatCase ? 0.5f : isUintCase ? 0.5f : 0.1f;
3427 shaderSpec.resultBias = isBoolCase ? 0.0f : isFloatCase ? 0.5f : isUintCase ? 0.0f : 0.5f;
3428 shaderSpec.referenceScale = shaderSpec.resultScale;
3429 shaderSpec.referenceBias = shaderSpec.resultBias;
3430
3431 float rangeMin = isBoolCase ? -1.0f : isFloatCase ? -1.0f : isUintCase ? 0.0f : -5.0f;
3432 float rangeMax = isBoolCase ? 1.0f : isFloatCase ? 1.0f : isUintCase ? 2.0f : 5.0f;
3433
3434 shaderSpec.inputs[0] = ShaderValue(TYPE_BOOL, -1.0f, 1.0f);
3435 shaderSpec.inputs[1] = ShaderValue(curType, rangeMin, rangeMax);
3436 shaderSpec.inputs[2] = ShaderValue(curType, rangeMin, rangeMax);
3437
3438 selectionGroup->addChild(new ShaderOperatorCase(m_context, name.c_str(), "", isVertexCase, evalFunc,
3439 "res = in0 ? in1 : in2;", shaderSpec));
3440 }
3441 }
3442 }
3443
3444 // The sequence operator (comma).
3445
3446 TestCaseGroup *sequenceGroup = new TestCaseGroup(m_context, "sequence", "Sequence operator tests");
3447 addChild(sequenceGroup);
3448
3449 TestCaseGroup *sequenceNoSideEffGroup =
3450 new TestCaseGroup(m_context, "no_side_effects", "Sequence tests without side-effects");
3451 TestCaseGroup *sequenceSideEffGroup =
3452 new TestCaseGroup(m_context, "side_effects", "Sequence tests with side-effects");
3453 sequenceGroup->addChild(sequenceNoSideEffGroup);
3454 sequenceGroup->addChild(sequenceSideEffGroup);
3455
3456 static const struct
3457 {
3458 bool containsSideEffects;
3459 const char *caseName;
3460 const char *expressionStr;
3461 int numInputs;
3462 DataType inputTypes[MAX_INPUTS];
3463 DataType resultType;
3464 ShaderEvalFunc evalFunc;
3465 } s_sequenceCases[] = {{false,
3466 "vec4",
3467 "in0, in2 + in1, in1 + in0",
3468 3,
3469 {TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4},
3470 TYPE_FLOAT_VEC4,
3471 evalSequenceNoSideEffCase0},
3472 {false,
3473 "float_uint",
3474 "in0 + in2, in1 + in1",
3475 3,
3476 {TYPE_FLOAT, TYPE_UINT, TYPE_FLOAT},
3477 TYPE_UINT,
3478 evalSequenceNoSideEffCase1},
3479 {false,
3480 "bool_vec2",
3481 "in0 && in1, in0, ivec2(vec2(in0) + in2)",
3482 3,
3483 {TYPE_BOOL, TYPE_BOOL, TYPE_FLOAT_VEC2},
3484 TYPE_INT_VEC2,
3485 evalSequenceNoSideEffCase2},
3486 {false,
3487 "vec4_ivec4_bvec4",
3488 "in0 + vec4(in1), in2, in1",
3489 3,
3490 {TYPE_FLOAT_VEC4, TYPE_INT_VEC4, TYPE_BOOL_VEC4},
3491 TYPE_INT_VEC4,
3492 evalSequenceNoSideEffCase3},
3493
3494 {true,
3495 "vec4",
3496 "in0++, in1 = in0 + in2, in2 = in1",
3497 3,
3498 {TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4},
3499 TYPE_FLOAT_VEC4,
3500 evalSequenceSideEffCase0},
3501 {true,
3502 "float_uint",
3503 "in1++, in0 = float(in1), in1 = uint(in0 + in2)",
3504 3,
3505 {TYPE_FLOAT, TYPE_UINT, TYPE_FLOAT},
3506 TYPE_UINT,
3507 evalSequenceSideEffCase1},
3508 {true,
3509 "bool_vec2",
3510 "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)",
3511 3,
3512 {TYPE_BOOL, TYPE_BOOL, TYPE_FLOAT_VEC2},
3513 TYPE_INT_VEC2,
3514 evalSequenceSideEffCase2},
3515 {true,
3516 "vec4_ivec4_bvec4",
3517 "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++",
3518 3,
3519 {TYPE_FLOAT_VEC4, TYPE_INT_VEC4, TYPE_BOOL_VEC4},
3520 TYPE_INT_VEC4,
3521 evalSequenceSideEffCase3}};
3522
3523 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_sequenceCases); caseNdx++)
3524 {
3525 for (int precision = 0; precision < (int)PRECISION_LAST; precision++)
3526 {
3527 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
3528 {
3529 ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
3530 ShaderDataSpec shaderSpec;
3531 const char *shaderTypeName = getShaderTypeName(shaderType);
3532 bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX;
3533
3534 string name = string("") + getPrecisionName((Precision)precision) + "_" +
3535 s_sequenceCases[caseNdx].caseName + "_" + shaderTypeName;
3536
3537 shaderSpec.numInputs = s_sequenceCases[caseNdx].numInputs;
3538 shaderSpec.precision = (Precision)precision;
3539 shaderSpec.output = s_sequenceCases[caseNdx].resultType;
3540 shaderSpec.resultScale = 0.5f;
3541 shaderSpec.resultBias = 0.0f;
3542 shaderSpec.referenceScale = shaderSpec.resultScale;
3543 shaderSpec.referenceBias = shaderSpec.resultBias;
3544
3545 for (int inputNdx = 0; inputNdx < s_sequenceCases[caseNdx].numInputs; inputNdx++)
3546 {
3547 DataType type = s_sequenceCases[caseNdx].inputTypes[inputNdx];
3548 float rangeMin = isDataTypeFloatOrVec(type) ? -0.5f :
3549 isDataTypeIntOrIVec(type) ? -2.0f :
3550 isDataTypeUintOrUVec(type) ? 0.0f :
3551 -1.0f;
3552 float rangeMax = isDataTypeFloatOrVec(type) ? 0.5f :
3553 isDataTypeIntOrIVec(type) ? 2.0f :
3554 isDataTypeUintOrUVec(type) ? 2.0f :
3555 1.0f;
3556
3557 shaderSpec.inputs[inputNdx] = ShaderValue(type, rangeMin, rangeMax);
3558 }
3559
3560 string expression = string("res = (") + s_sequenceCases[caseNdx].expressionStr + ");";
3561
3562 TestCaseGroup *group =
3563 s_sequenceCases[caseNdx].containsSideEffects ? sequenceSideEffGroup : sequenceNoSideEffGroup;
3564 group->addChild(new ShaderOperatorCase(m_context, name.c_str(), "", isVertexCase,
3565 s_sequenceCases[caseNdx].evalFunc, expression.c_str(),
3566 shaderSpec));
3567 }
3568 }
3569 }
3570 }
3571
3572 } // namespace Functional
3573 } // namespace gles3
3574 } // namespace deqp
3575