1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Shader operators tests.
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktShaderRenderOperatorTests.hpp"
27 #include "vktShaderRender.hpp"
28 #include "tcuVectorUtil.hpp"
29 #include "deStringUtil.hpp"
30
31 #include <limits>
32
33 using namespace tcu;
34 using namespace glu;
35
36 namespace vkt
37 {
38 namespace sr
39 {
40 namespace
41 {
42
43 using de::clamp;
44 using de::max;
45 using de::min;
46
logicalAnd(bool a,bool b)47 inline bool logicalAnd(bool a, bool b)
48 {
49 return (a && b);
50 }
logicalOr(bool a,bool b)51 inline bool logicalOr(bool a, bool b)
52 {
53 return (a || b);
54 }
logicalXor(bool a,bool b)55 inline bool logicalXor(bool a, bool b)
56 {
57 return (a != b);
58 }
59
60 // \note stdlib.h defines div() that is not compatible with the macros.
61 template <typename T>
div(T a,T b)62 inline T div(T a, T b)
63 {
64 return a / b;
65 }
66
67 template <typename T>
leftShift(T value,int amount)68 inline T leftShift(T value, int amount)
69 {
70 return value << amount;
71 }
72
rightShift(uint32_t value,int amount)73 inline uint32_t rightShift(uint32_t value, int amount)
74 {
75 return value >> amount;
76 }
rightShift(int value,int amount)77 inline int rightShift(int value, int amount)
78 {
79 return (value >> amount) | (value >= 0 ? 0 : ~(~0U >> amount));
80 } // \note Arithmetic shift.
81
82 template <typename T, int Size>
leftShift(const Vector<T,Size> & value,const Vector<int,Size> & amount)83 Vector<T, Size> leftShift(const Vector<T, Size> &value, const Vector<int, Size> &amount)
84 {
85 Vector<T, Size> result;
86 for (int i = 0; i < Size; i++)
87 result[i] = leftShift(value[i], amount[i]);
88 return result;
89 }
90
91 template <typename T, int Size>
rightShift(const Vector<T,Size> & value,const Vector<int,Size> & amount)92 Vector<T, Size> rightShift(const Vector<T, Size> &value, const Vector<int, Size> &amount)
93 {
94 Vector<T, Size> result;
95 for (int i = 0; i < Size; i++)
96 result[i] = rightShift(value[i], amount[i]);
97 return result;
98 }
99
100 template <typename T, int Size>
leftShiftVecScalar(const Vector<T,Size> & value,int amount)101 Vector<T, Size> leftShiftVecScalar(const Vector<T, Size> &value, int amount)
102 {
103 return leftShift(value, Vector<int, Size>(amount));
104 }
105 template <typename T, int Size>
rightShiftVecScalar(const Vector<T,Size> & value,int amount)106 Vector<T, Size> rightShiftVecScalar(const Vector<T, Size> &value, int amount)
107 {
108 return rightShift(value, Vector<int, Size>(amount));
109 }
110
111 template <typename T, int Size>
minVecScalar(const Vector<T,Size> & v,T s)112 inline Vector<T, Size> minVecScalar(const Vector<T, Size> &v, T s)
113 {
114 Vector<T, Size> res;
115 for (int i = 0; i < Size; i++)
116 res[i] = min(v[i], s);
117 return res;
118 }
119
120 template <typename T, int Size>
maxVecScalar(const Vector<T,Size> & v,T s)121 inline Vector<T, Size> maxVecScalar(const Vector<T, Size> &v, T s)
122 {
123 Vector<T, Size> res;
124 for (int i = 0; i < Size; i++)
125 res[i] = max(v[i], s);
126 return res;
127 }
128
129 template <typename T, int Size>
clampVecScalarScalar(const Vector<T,Size> & v,T s0,T s1)130 inline Vector<T, Size> clampVecScalarScalar(const Vector<T, Size> &v, T s0, T s1)
131 {
132 Vector<T, Size> res;
133 for (int i = 0; i < Size; i++)
134 res[i] = clamp(v[i], s0, s1);
135 return res;
136 }
137
138 template <typename T, int Size>
mixVecVecScalar(const Vector<T,Size> & v0,const Vector<T,Size> & v1,T s)139 inline Vector<T, Size> mixVecVecScalar(const Vector<T, Size> &v0, const Vector<T, Size> &v1, T s)
140 {
141 Vector<T, Size> res;
142 for (int i = 0; i < Size; i++)
143 res[i] = mix(v0[i], v1[i], s);
144 return res;
145 }
146
147 template <typename T, int Size>
stepScalarVec(T s,const Vector<T,Size> & v)148 inline Vector<T, Size> stepScalarVec(T s, const Vector<T, Size> &v)
149 {
150 Vector<T, Size> res;
151 for (int i = 0; i < Size; i++)
152 res[i] = step(s, v[i]);
153 return res;
154 }
155
156 template <typename T, int Size>
smoothStepScalarScalarVec(T s0,T s1,const Vector<T,Size> & v)157 inline Vector<T, Size> smoothStepScalarScalarVec(T s0, T s1, const Vector<T, Size> &v)
158 {
159 Vector<T, Size> res;
160 for (int i = 0; i < Size; i++)
161 res[i] = smoothStep(s0, s1, v[i]);
162 return res;
163 }
164
addOne(int v)165 inline int addOne(int v)
166 {
167 return v + 1;
168 }
subOne(int v)169 inline int subOne(int v)
170 {
171 return v - 1;
172 }
addOne(uint32_t v)173 inline uint32_t addOne(uint32_t v)
174 {
175 return v + 1;
176 }
subOne(uint32_t v)177 inline uint32_t subOne(uint32_t v)
178 {
179 return v - 1;
180 }
181
182 template <int Size>
addOne(const Vector<float,Size> & v)183 inline Vector<float, Size> addOne(const Vector<float, Size> &v)
184 {
185 return v + 1.0f;
186 }
187 template <int Size>
subOne(const Vector<float,Size> & v)188 inline Vector<float, Size> subOne(const Vector<float, Size> &v)
189 {
190 return v - 1.0f;
191 }
192 template <int Size>
addOne(const Vector<int,Size> & v)193 inline Vector<int, Size> addOne(const Vector<int, Size> &v)
194 {
195 return v + 1;
196 }
197 template <int Size>
subOne(const Vector<int,Size> & v)198 inline Vector<int, Size> subOne(const Vector<int, Size> &v)
199 {
200 return v - 1;
201 }
202 template <int Size>
addOne(const Vector<uint32_t,Size> & v)203 inline Vector<uint32_t, Size> addOne(const Vector<uint32_t, Size> &v)
204 {
205 return v + 1U;
206 }
207 template <int Size>
subOne(const Vector<uint32_t,Size> & v)208 inline Vector<uint32_t, Size> subOne(const Vector<uint32_t, Size> &v)
209 {
210 return (v.asInt() - 1).asUint();
211 }
212
213 template <typename T>
selection(bool cond,T a,T b)214 inline T selection(bool cond, T a, T b)
215 {
216 return cond ? a : b;
217 }
218
219 // Vec-scalar and scalar-vec binary operators.
220
221 // \note This one is done separately due to how the overloaded minus operator is implemented for vector-scalar operands.
222 template <int Size>
subVecScalar(const Vector<uint32_t,Size> & v,uint32_t s)223 inline Vector<uint32_t, Size> subVecScalar(const Vector<uint32_t, Size> &v, uint32_t s)
224 {
225 return (v.asInt() - (int)s).asUint();
226 }
227
228 template <typename T, int Size>
addVecScalar(const Vector<T,Size> & v,T s)229 inline Vector<T, Size> addVecScalar(const Vector<T, Size> &v, T s)
230 {
231 return v + s;
232 }
233 template <typename T, int Size>
subVecScalar(const Vector<T,Size> & v,T s)234 inline Vector<T, Size> subVecScalar(const Vector<T, Size> &v, T s)
235 {
236 return v - s;
237 }
238 template <typename T, int Size>
mulVecScalar(const Vector<T,Size> & v,T s)239 inline Vector<T, Size> mulVecScalar(const Vector<T, Size> &v, T s)
240 {
241 return v * s;
242 }
243 template <typename T, int Size>
divVecScalar(const Vector<T,Size> & v,T s)244 inline Vector<T, Size> divVecScalar(const Vector<T, Size> &v, T s)
245 {
246 return v / s;
247 }
248 template <typename T, int Size>
modVecScalar(const Vector<T,Size> & v,T s)249 inline Vector<T, Size> modVecScalar(const Vector<T, Size> &v, T s)
250 {
251 return mod(v, Vector<T, Size>(s));
252 }
253 template <typename T, int Size>
bitwiseAndVecScalar(const Vector<T,Size> & v,T s)254 inline Vector<T, Size> bitwiseAndVecScalar(const Vector<T, Size> &v, T s)
255 {
256 return bitwiseAnd(v, Vector<T, Size>(s));
257 }
258 template <typename T, int Size>
bitwiseOrVecScalar(const Vector<T,Size> & v,T s)259 inline Vector<T, Size> bitwiseOrVecScalar(const Vector<T, Size> &v, T s)
260 {
261 return bitwiseOr(v, Vector<T, Size>(s));
262 }
263 template <typename T, int Size>
bitwiseXorVecScalar(const Vector<T,Size> & v,T s)264 inline Vector<T, Size> bitwiseXorVecScalar(const Vector<T, Size> &v, T s)
265 {
266 return bitwiseXor(v, Vector<T, Size>(s));
267 }
268
269 template <typename T, int Size>
addScalarVec(T s,const Vector<T,Size> & v)270 inline Vector<T, Size> addScalarVec(T s, const Vector<T, Size> &v)
271 {
272 return s + v;
273 }
274 template <typename T, int Size>
subScalarVec(T s,const Vector<T,Size> & v)275 inline Vector<T, Size> subScalarVec(T s, const Vector<T, Size> &v)
276 {
277 return s - v;
278 }
279 template <typename T, int Size>
mulScalarVec(T s,const Vector<T,Size> & v)280 inline Vector<T, Size> mulScalarVec(T s, const Vector<T, Size> &v)
281 {
282 return s * v;
283 }
284 template <typename T, int Size>
divScalarVec(T s,const Vector<T,Size> & v)285 inline Vector<T, Size> divScalarVec(T s, const Vector<T, Size> &v)
286 {
287 return s / v;
288 }
289 template <typename T, int Size>
modScalarVec(T s,const Vector<T,Size> & v)290 inline Vector<T, Size> modScalarVec(T s, const Vector<T, Size> &v)
291 {
292 return mod(Vector<T, Size>(s), v);
293 }
294 template <typename T, int Size>
bitwiseAndScalarVec(T s,const Vector<T,Size> & v)295 inline Vector<T, Size> bitwiseAndScalarVec(T s, const Vector<T, Size> &v)
296 {
297 return bitwiseAnd(Vector<T, Size>(s), v);
298 }
299 template <typename T, int Size>
bitwiseOrScalarVec(T s,const Vector<T,Size> & v)300 inline Vector<T, Size> bitwiseOrScalarVec(T s, const Vector<T, Size> &v)
301 {
302 return bitwiseOr(Vector<T, Size>(s), v);
303 }
304 template <typename T, int Size>
bitwiseXorScalarVec(T s,const Vector<T,Size> & v)305 inline Vector<T, Size> bitwiseXorScalarVec(T s, const Vector<T, Size> &v)
306 {
307 return bitwiseXor(Vector<T, Size>(s), v);
308 }
309
310 // Reference functions for specific sequence operations for the sequence operator tests.
311
312 // Reference for expression "in0, in2 + in1, in1 + in0"
sequenceNoSideEffCase0(const Vec4 & in0,const Vec4 & in1,const Vec4 & in2)313 inline Vec4 sequenceNoSideEffCase0(const Vec4 &in0, const Vec4 &in1, const Vec4 &in2)
314 {
315 DE_UNREF(in2);
316 return in1 + in0;
317 }
318 // Reference for expression "in0, in2 + in1, in1 + in0"
sequenceNoSideEffCase1(float in0,uint32_t in1,float in2)319 inline uint32_t sequenceNoSideEffCase1(float in0, uint32_t in1, float in2)
320 {
321 DE_UNREF(in0);
322 DE_UNREF(in2);
323 return in1 + in1;
324 }
325 // Reference for expression "in0 && in1, in0, ivec2(vec2(in0) + in2)"
sequenceNoSideEffCase2(bool in0,bool in1,const Vec2 & in2)326 inline IVec2 sequenceNoSideEffCase2(bool in0, bool in1, const Vec2 &in2)
327 {
328 DE_UNREF(in1);
329 return IVec2((int)((float)in0 + in2.x()), (int)((float)in0 + in2.y()));
330 }
331 // Reference for expression "in0 + vec4(in1), in2, in1"
sequenceNoSideEffCase3(const Vec4 & in0,const IVec4 & in1,const BVec4 & in2)332 inline IVec4 sequenceNoSideEffCase3(const Vec4 &in0, const IVec4 &in1, const BVec4 &in2)
333 {
334 DE_UNREF(in0);
335 DE_UNREF(in2);
336 return in1;
337 }
338 // Reference for expression "in0++, in1 = in0 + in2, in2 = in1"
sequenceSideEffCase0(const Vec4 & in0,const Vec4 & in1,const Vec4 & in2)339 inline Vec4 sequenceSideEffCase0(const Vec4 &in0, const Vec4 &in1, const Vec4 &in2)
340 {
341 DE_UNREF(in1);
342 return in0 + 1.0f + in2;
343 }
344 // Reference for expression "in1++, in0 = float(in1), in1 = uint(in0 + in2)"
sequenceSideEffCase1(float in0,uint32_t in1,float in2)345 inline uint32_t sequenceSideEffCase1(float in0, uint32_t in1, float in2)
346 {
347 DE_UNREF(in0);
348 return (uint32_t)(float(in1) + 1.0f + in2);
349 }
350 // Reference for expression "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)"
sequenceSideEffCase2(bool in0,bool in1,const Vec2 & in2)351 inline IVec2 sequenceSideEffCase2(bool in0, bool in1, const Vec2 &in2)
352 {
353 DE_UNREF(in1);
354 return (in2 + Vec2(1.0f) + Vec2((float)in0)).asInt();
355 }
356 // Reference for expression "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++"
sequenceSideEffCase3(const Vec4 & in0,const IVec4 & in1,const BVec4 & in2)357 inline IVec4 sequenceSideEffCase3(const Vec4 &in0, const IVec4 &in1, const BVec4 &in2)
358 {
359 return in1 + (in0 + Vec4((float)in2.x(), (float)in2.y(), (float)in2.z(), (float)in2.w())).asInt();
360 }
361
362 // ShaderEvalFunc-type wrappers for the above functions.
evalSequenceNoSideEffCase0(ShaderEvalContext & ctx)363 void evalSequenceNoSideEffCase0(ShaderEvalContext &ctx)
364 {
365 ctx.color = sequenceNoSideEffCase0(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0),
366 ctx.in[2].swizzle(0, 3, 2, 1));
367 }
evalSequenceNoSideEffCase1(ShaderEvalContext & ctx)368 void evalSequenceNoSideEffCase1(ShaderEvalContext &ctx)
369 {
370 ctx.color.x() = (float)sequenceNoSideEffCase1(ctx.in[0].z(), (uint32_t)ctx.in[1].x(), ctx.in[2].y());
371 }
evalSequenceNoSideEffCase2(ShaderEvalContext & ctx)372 void evalSequenceNoSideEffCase2(ShaderEvalContext &ctx)
373 {
374 ctx.color.yz() =
375 sequenceNoSideEffCase2(ctx.in[0].z() > 0.0f, ctx.in[1].x() > 0.0f, ctx.in[2].swizzle(2, 1)).asFloat();
376 }
evalSequenceNoSideEffCase3(ShaderEvalContext & ctx)377 void evalSequenceNoSideEffCase3(ShaderEvalContext &ctx)
378 {
379 ctx.color = sequenceNoSideEffCase3(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0).asInt(),
380 greaterThan(ctx.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f)))
381 .asFloat();
382 }
evalSequenceSideEffCase0(ShaderEvalContext & ctx)383 void evalSequenceSideEffCase0(ShaderEvalContext &ctx)
384 {
385 ctx.color = sequenceSideEffCase0(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0),
386 ctx.in[2].swizzle(0, 3, 2, 1));
387 }
evalSequenceSideEffCase1(ShaderEvalContext & ctx)388 void evalSequenceSideEffCase1(ShaderEvalContext &ctx)
389 {
390 ctx.color.x() = (float)sequenceSideEffCase1(ctx.in[0].z(), (uint32_t)ctx.in[1].x(), ctx.in[2].y());
391 }
evalSequenceSideEffCase2(ShaderEvalContext & ctx)392 void evalSequenceSideEffCase2(ShaderEvalContext &ctx)
393 {
394 ctx.color.yz() =
395 sequenceSideEffCase2(ctx.in[0].z() > 0.0f, ctx.in[1].x() > 0.0f, ctx.in[2].swizzle(2, 1)).asFloat();
396 }
evalSequenceSideEffCase3(ShaderEvalContext & ctx)397 void evalSequenceSideEffCase3(ShaderEvalContext &ctx)
398 {
399 ctx.color = sequenceSideEffCase3(ctx.in[0].swizzle(1, 2, 3, 0), ctx.in[1].swizzle(3, 2, 1, 0).asInt(),
400 greaterThan(ctx.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f)))
401 .asFloat();
402 }
403
stringJoin(const std::vector<std::string> & elems,const std::string & delim)404 static std::string stringJoin(const std::vector<std::string> &elems, const std::string &delim)
405 {
406 std::string result;
407 for (int i = 0; i < (int)elems.size(); i++)
408 result += (i > 0 ? delim : "") + elems[i];
409 return result;
410 }
411
twoValuedVec4(const std::string & first,const std::string & second,const BVec4 & firstMask)412 static std::string twoValuedVec4(const std::string &first, const std::string &second, const BVec4 &firstMask)
413 {
414 std::vector<std::string> elems(4);
415 for (int i = 0; i < 4; i++)
416 elems[i] = firstMask[i] ? first : second;
417
418 return "vec4(" + stringJoin(elems, ", ") + ")";
419 }
420
421 enum
422 {
423 MAX_INPUTS = 3
424 };
425
426 enum PrecisionMask
427 {
428 PRECMASK_NA = 0, //!< Precision not applicable (booleans)
429 PRECMASK_MEDIUMP = (1 << PRECISION_MEDIUMP),
430 PRECMASK_HIGHP = (1 << PRECISION_HIGHP),
431
432 PRECMASK_ALL = PRECMASK_MEDIUMP | PRECMASK_HIGHP
433 };
434
435 enum ValueType
436 {
437 VALUE_NONE = 0,
438 VALUE_FLOAT = (1 << 0), // float scalar
439 VALUE_FLOAT_VEC = (1 << 1), // float vector
440 VALUE_FLOAT_GENTYPE = (1 << 2), // float scalar/vector
441 VALUE_VEC3 = (1 << 3), // vec3 only
442 VALUE_MATRIX = (1 << 4), // matrix
443 VALUE_BOOL = (1 << 5), // boolean scalar
444 VALUE_BOOL_VEC = (1 << 6), // boolean vector
445 VALUE_BOOL_GENTYPE = (1 << 7), // boolean scalar/vector
446 VALUE_INT = (1 << 8), // int scalar
447 VALUE_INT_VEC = (1 << 9), // int vector
448 VALUE_INT_GENTYPE = (1 << 10), // int scalar/vector
449 VALUE_UINT = (1 << 11), // uint scalar
450 VALUE_UINT_VEC = (1 << 12), // uint vector
451 VALUE_UINT_GENTYPE = (1 << 13), // uint scalar/vector
452
453 // Shorthands.
454 F = VALUE_FLOAT,
455 FV = VALUE_FLOAT_VEC,
456 GT = VALUE_FLOAT_GENTYPE,
457 V3 = VALUE_VEC3,
458 M = VALUE_MATRIX,
459 B = VALUE_BOOL,
460 BV = VALUE_BOOL_VEC,
461 BGT = VALUE_BOOL_GENTYPE,
462 I = VALUE_INT,
463 IV = VALUE_INT_VEC,
464 IGT = VALUE_INT_GENTYPE,
465 U = VALUE_UINT,
466 UV = VALUE_UINT_VEC,
467 UGT = VALUE_UINT_GENTYPE
468 };
469
isScalarType(ValueType type)470 static inline bool isScalarType(ValueType type)
471 {
472 return type == VALUE_FLOAT || type == VALUE_BOOL || type == VALUE_INT || type == VALUE_UINT;
473 }
474
isFloatType(ValueType type)475 static inline bool isFloatType(ValueType type)
476 {
477 return (type & (VALUE_FLOAT | VALUE_FLOAT_VEC | VALUE_FLOAT_GENTYPE)) != 0;
478 }
479
isIntType(ValueType type)480 static inline bool isIntType(ValueType type)
481 {
482 return (type & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0;
483 }
484
isUintType(ValueType type)485 static inline bool isUintType(ValueType type)
486 {
487 return (type & (VALUE_UINT | VALUE_UINT_VEC | VALUE_UINT_GENTYPE)) != 0;
488 }
489
isBoolType(ValueType type)490 static inline bool isBoolType(ValueType type)
491 {
492 return (type & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0;
493 }
494
495 struct Value
496 {
Valuevkt::sr::__anoncb2548460111::Value497 Value(ValueType valueType_, const float rangeMin_, const float rangeMax_)
498 : valueType(valueType_)
499 , rangeMin(rangeMin_)
500 , rangeMax(rangeMax_)
501 {
502 }
503
504 ValueType valueType;
505 float rangeMin;
506 float rangeMax;
507 };
508
509 enum OperationType
510 {
511 FUNCTION = 0,
512 OPERATOR,
513 SIDE_EFFECT_OPERATOR // Test the side-effect (as opposed to the result) of a side-effect operator.
514 };
515
516 struct BuiltinFuncInfo
517 {
BuiltinFuncInfovkt::sr::__anoncb2548460111::BuiltinFuncInfo518 BuiltinFuncInfo(const char *caseName_, const char *shaderFuncName_, ValueType outValue_, Value input0_,
519 Value input1_, Value input2_, const float resultScale_, const float resultBias_,
520 uint32_t precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_,
521 ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_, OperationType type_ = FUNCTION,
522 bool isUnaryPrefix_ = true)
523 : caseName(caseName_)
524 , shaderFuncName(shaderFuncName_)
525 , outValue(outValue_)
526 , input0(input0_)
527 , input1(input1_)
528 , input2(input2_)
529 , resultScale(resultScale_)
530 , resultBias(resultBias_)
531 , referenceScale(resultScale_)
532 , referenceBias(resultBias_)
533 , precisionMask(precisionMask_)
534 , evalFuncScalar(evalFuncScalar_)
535 , evalFuncVec2(evalFuncVec2_)
536 , evalFuncVec3(evalFuncVec3_)
537 , evalFuncVec4(evalFuncVec4_)
538 , type(type_)
539 , isUnaryPrefix(isUnaryPrefix_)
540 {
541 }
542
BuiltinFuncInfovkt::sr::__anoncb2548460111::BuiltinFuncInfo543 BuiltinFuncInfo(const char *caseName_, const char *shaderFuncName_, ValueType outValue_, Value input0_,
544 Value input1_, Value input2_, const float resultScale_, const float resultBias_,
545 const float referenceScale_, const float referenceBias_, uint32_t precisionMask_,
546 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
547 ShaderEvalFunc evalFuncVec4_, OperationType type_ = FUNCTION, bool isUnaryPrefix_ = true)
548 : caseName(caseName_)
549 , shaderFuncName(shaderFuncName_)
550 , outValue(outValue_)
551 , input0(input0_)
552 , input1(input1_)
553 , input2(input2_)
554 , resultScale(resultScale_)
555 , resultBias(resultBias_)
556 , referenceScale(referenceScale_)
557 , referenceBias(referenceBias_)
558 , precisionMask(precisionMask_)
559 , evalFuncScalar(evalFuncScalar_)
560 , evalFuncVec2(evalFuncVec2_)
561 , evalFuncVec3(evalFuncVec3_)
562 , evalFuncVec4(evalFuncVec4_)
563 , type(type_)
564 , isUnaryPrefix(isUnaryPrefix_)
565 {
566 }
567
568 const char *caseName; //!< Name of case.
569 const char *shaderFuncName; //!< Name in shading language.
570 ValueType outValue;
571 Value input0;
572 Value input1;
573 Value input2;
574 float resultScale;
575 float resultBias;
576 float referenceScale;
577 float referenceBias;
578 uint32_t precisionMask;
579 ShaderEvalFunc evalFuncScalar;
580 ShaderEvalFunc evalFuncVec2;
581 ShaderEvalFunc evalFuncVec3;
582 ShaderEvalFunc evalFuncVec4;
583 OperationType type;
584 bool isUnaryPrefix; //!< Whether a unary operator is a prefix operator; redundant unless unary.
585 };
586
BuiltinOperInfo(const char * caseName_,const char * shaderFuncName_,ValueType outValue_,Value input0_,Value input1_,Value input2_,const float resultScale_,const float resultBias_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)587 static inline BuiltinFuncInfo BuiltinOperInfo(const char *caseName_, const char *shaderFuncName_, ValueType outValue_,
588 Value input0_, Value input1_, Value input2_, const float resultScale_,
589 const float resultBias_, uint32_t precisionMask_,
590 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_,
591 ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_)
592 {
593 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
594 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
595 evalFuncVec4_, OPERATOR);
596 }
597
598 // For postfix (unary) operators.
BuiltinPostOperInfo(const char * caseName_,const char * shaderFuncName_,ValueType outValue_,Value input0_,Value input1_,Value input2_,const float resultScale_,const float resultBias_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)599 static inline BuiltinFuncInfo BuiltinPostOperInfo(const char *caseName_, const char *shaderFuncName_,
600 ValueType outValue_, Value input0_, Value input1_, Value input2_,
601 const float resultScale_, const float resultBias_,
602 uint32_t precisionMask_, ShaderEvalFunc evalFuncScalar_,
603 ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
604 ShaderEvalFunc evalFuncVec4_)
605 {
606 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
607 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
608 evalFuncVec4_, OPERATOR, false);
609 }
610
BuiltinSideEffOperInfo(const char * caseName_,const char * shaderFuncName_,ValueType outValue_,Value input0_,Value input1_,Value input2_,const float resultScale_,const float resultBias_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)611 static inline BuiltinFuncInfo BuiltinSideEffOperInfo(const char *caseName_, const char *shaderFuncName_,
612 ValueType outValue_, Value input0_, Value input1_, Value input2_,
613 const float resultScale_, const float resultBias_,
614 uint32_t precisionMask_, ShaderEvalFunc evalFuncScalar_,
615 ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_,
616 ShaderEvalFunc evalFuncVec4_)
617 {
618 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
619 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
620 evalFuncVec4_, SIDE_EFFECT_OPERATOR);
621 }
622
623 // For postfix (unary) operators, testing side-effect.
BuiltinPostSideEffOperInfo(const char * caseName_,const char * shaderFuncName_,ValueType outValue_,Value input0_,Value input1_,Value input2_,const float resultScale_,const float resultBias_,uint32_t precisionMask_,ShaderEvalFunc evalFuncScalar_,ShaderEvalFunc evalFuncVec2_,ShaderEvalFunc evalFuncVec3_,ShaderEvalFunc evalFuncVec4_)624 static inline BuiltinFuncInfo BuiltinPostSideEffOperInfo(const char *caseName_, const char *shaderFuncName_,
625 ValueType outValue_, Value input0_, Value input1_,
626 Value input2_, const float resultScale_,
627 const float resultBias_, uint32_t precisionMask_,
628 ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_,
629 ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_)
630 {
631 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_,
632 resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_,
633 evalFuncVec4_, SIDE_EFFECT_OPERATOR, false);
634 }
635
636 // BuiltinFuncGroup
637
638 struct BuiltinFuncGroup
639 {
BuiltinFuncGroupvkt::sr::__anoncb2548460111::BuiltinFuncGroup640 BuiltinFuncGroup(const char *name_, const char *description_) : name(name_), description(description_)
641 {
642 }
operator <<vkt::sr::__anoncb2548460111::BuiltinFuncGroup643 BuiltinFuncGroup &operator<<(const BuiltinFuncInfo &info)
644 {
645 funcInfos.push_back(info);
646 return *this;
647 }
648
649 const char *name;
650 const char *description;
651 std::vector<BuiltinFuncInfo> funcInfos;
652 };
653
654 static const char *s_inSwizzles[MAX_INPUTS][4] = {{"z", "wy", "zxy", "yzwx"},
655 {"x", "yx", "yzx", "wzyx"},
656 {"y", "zy", "wyz", "xwzy"}};
657
658 static const char *s_outSwizzles[] = {"x", "yz", "xyz", "xyzw"};
659
660 static const BVec4 s_outSwizzleChannelMasks[] = {BVec4(true, false, false, false), BVec4(false, true, true, false),
661 BVec4(true, true, true, false), BVec4(true, true, true, true)};
662
663 // OperatorShaderEvaluator
664
665 class OperatorShaderEvaluator : public ShaderEvaluator
666 {
667 public:
OperatorShaderEvaluator(const ShaderEvalFunc evalFunc,const float scale,const float bias,int resultScalarSize)668 OperatorShaderEvaluator(const ShaderEvalFunc evalFunc, const float scale, const float bias, int resultScalarSize)
669 : m_evalFunc(evalFunc)
670 , m_resultScalarSize(resultScalarSize)
671 , m_evaluatedScale(scale)
672 , m_evaluatedBias(bias)
673 {
674 DE_ASSERT(de::inRange(resultScalarSize, 1, 4));
675 }
676
~OperatorShaderEvaluator(void)677 virtual ~OperatorShaderEvaluator(void)
678 {
679 }
680
evaluate(ShaderEvalContext & ctx) const681 virtual void evaluate(ShaderEvalContext &ctx) const
682 {
683 m_evalFunc(ctx);
684
685 for (int channelNdx = 0; channelNdx < 4; channelNdx++)
686 if (s_outSwizzleChannelMasks[m_resultScalarSize - 1][channelNdx])
687 ctx.color[channelNdx] = ctx.color[channelNdx] * m_evaluatedScale + m_evaluatedBias;
688 }
689
690 private:
691 const ShaderEvalFunc m_evalFunc;
692 const int m_resultScalarSize;
693
694 const float m_evaluatedScale;
695 const float m_evaluatedBias;
696 };
697
698 // Concrete value.
699
700 struct ShaderValue
701 {
ShaderValuevkt::sr::__anoncb2548460111::ShaderValue702 ShaderValue(DataType type_, const float rangeMin_, const float rangeMax_)
703 : type(type_)
704 , rangeMin(rangeMin_)
705 , rangeMax(rangeMax_)
706 {
707 }
708
ShaderValuevkt::sr::__anoncb2548460111::ShaderValue709 ShaderValue(void) : type(TYPE_LAST), rangeMin(0.0f), rangeMax(0.0f)
710 {
711 }
712
713 DataType type;
714 float rangeMin;
715 float rangeMax;
716 };
717
718 struct ShaderDataSpec
719 {
ShaderDataSpecvkt::sr::__anoncb2548460111::ShaderDataSpec720 ShaderDataSpec(void)
721 : resultScale(1.0f)
722 , resultBias(0.0f)
723 , referenceScale(1.0f)
724 , referenceBias(0.0f)
725 , precision(PRECISION_LAST)
726 , output(TYPE_LAST)
727 , numInputs(0)
728 {
729 }
730
731 float resultScale;
732 float resultBias;
733 float referenceScale;
734 float referenceBias;
735 Precision precision;
736 DataType output;
737 int numInputs;
738 ShaderValue inputs[MAX_INPUTS];
739 };
740
741 // ShaderOperatorInstance
742
743 class ShaderOperatorCaseInstance : public ShaderRenderCaseInstance
744 {
745 public:
746 ShaderOperatorCaseInstance(Context &context, const bool isVertexCase, const ShaderEvaluator &evaluator,
747 const UniformSetup &uniformSetup, const ShaderDataSpec spec);
748 virtual ~ShaderOperatorCaseInstance(void);
749
750 private:
751 const ShaderDataSpec m_spec;
752 };
753
ShaderOperatorCaseInstance(Context & context,const bool isVertexCase,const ShaderEvaluator & evaluator,const UniformSetup & uniformSetup,const ShaderDataSpec spec)754 ShaderOperatorCaseInstance::ShaderOperatorCaseInstance(Context &context, const bool isVertexCase,
755 const ShaderEvaluator &evaluator,
756 const UniformSetup &uniformSetup, const ShaderDataSpec spec)
757 : ShaderRenderCaseInstance(context, isVertexCase, evaluator, uniformSetup, DE_NULL, IMAGE_BACKING_MODE_REGULAR,
758 (isVertexCase ? 92 : GRID_SIZE_DEFAULT_FRAGMENT))
759 , m_spec(spec)
760 {
761 // Setup the user attributes.
762 m_userAttribTransforms.resize(m_spec.numInputs);
763 for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
764 {
765 const ShaderValue &v = m_spec.inputs[inputNdx];
766 DE_ASSERT(v.type != TYPE_LAST);
767
768 const float rangeMin = v.rangeMin;
769 const float rangeMax = v.rangeMax;
770 const float scale = rangeMax - rangeMin;
771 const float minBias = rangeMin;
772 const float maxBias = rangeMax;
773 Mat4 attribMatrix;
774
775 for (int rowNdx = 0; rowNdx < 4; rowNdx++)
776 {
777 Vec4 row;
778
779 switch ((rowNdx + inputNdx) % 4)
780 {
781 case 0:
782 row = Vec4(scale, 0.0f, 0.0f, minBias);
783 break;
784 case 1:
785 row = Vec4(0.0f, scale, 0.0f, minBias);
786 break;
787 case 2:
788 row = Vec4(-scale, 0.0f, 0.0f, maxBias);
789 break;
790 case 3:
791 row = Vec4(0.0f, -scale, 0.0f, maxBias);
792 break;
793 default:
794 DE_ASSERT(false);
795 }
796
797 attribMatrix.setRow(rowNdx, row);
798 }
799
800 m_userAttribTransforms[inputNdx] = attribMatrix;
801
802 const uint32_t location = 4u + inputNdx;
803 switch (inputNdx)
804 {
805 case 0:
806 useAttribute(location, A_IN0);
807 break;
808 case 1:
809 useAttribute(location, A_IN1);
810 break;
811 case 2:
812 useAttribute(location, A_IN2);
813 break;
814 case 3:
815 useAttribute(location, A_IN3);
816 break;
817 default:
818 DE_ASSERT(false);
819 }
820 }
821 }
822
~ShaderOperatorCaseInstance(void)823 ShaderOperatorCaseInstance::~ShaderOperatorCaseInstance(void)
824 {
825 }
826
827 // ShaderOperatorCase
828
829 class ShaderOperatorCase : public ShaderRenderCase
830 {
831 public:
832 ShaderOperatorCase(tcu::TestContext &testCtx, const char *caseName, const bool isVertexCase,
833 const ShaderEvalFunc evalFunc, const std::string &shaderOp, const ShaderDataSpec &spec);
834 virtual ~ShaderOperatorCase(void);
835
836 virtual TestInstance *createInstance(Context &context) const;
837
838 protected:
839 void setupShaderData(void);
840
841 private:
842 ShaderOperatorCase(const ShaderOperatorCase &); // not allowed!
843 ShaderOperatorCase &operator=(const ShaderOperatorCase &); // not allowed!
844
845 const ShaderDataSpec m_spec;
846 const std::string m_shaderOp;
847 };
848
ShaderOperatorCase(tcu::TestContext & testCtx,const char * caseName,const bool isVertexCase,const ShaderEvalFunc evalFunc,const std::string & shaderOp,const ShaderDataSpec & spec)849 ShaderOperatorCase::ShaderOperatorCase(tcu::TestContext &testCtx, const char *caseName, const bool isVertexCase,
850 const ShaderEvalFunc evalFunc, const std::string &shaderOp,
851 const ShaderDataSpec &spec)
852 : ShaderRenderCase(testCtx, caseName, isVertexCase,
853 new OperatorShaderEvaluator(evalFunc, spec.referenceScale, spec.referenceBias,
854 getDataTypeScalarSize(spec.output)),
855 DE_NULL, DE_NULL)
856 , m_spec(spec)
857 , m_shaderOp(shaderOp)
858 {
859 setupShaderData();
860 }
861
createInstance(Context & context) const862 TestInstance *ShaderOperatorCase::createInstance(Context &context) const
863 {
864 DE_ASSERT(m_evaluator != DE_NULL);
865 DE_ASSERT(m_uniformSetup != DE_NULL);
866 return new ShaderOperatorCaseInstance(context, m_isVertexCase, *m_evaluator, *m_uniformSetup, m_spec);
867 }
868
setupShaderData(void)869 void ShaderOperatorCase::setupShaderData(void)
870 {
871 const char *precision = m_spec.precision != PRECISION_LAST ? getPrecisionName(m_spec.precision) : DE_NULL;
872 const char *inputPrecision[MAX_INPUTS];
873
874 std::ostringstream vtx;
875 std::ostringstream frag;
876 std::ostringstream &op = m_isVertexCase ? vtx : frag;
877
878 std::string header = "#version 310 es\n";
879
880 vtx << header;
881 frag << header;
882
883 // Compute precision for inputs.
884 for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
885 {
886 const bool isBoolVal = de::inRange<int>(m_spec.inputs[inputNdx].type, TYPE_BOOL, TYPE_BOOL_VEC4);
887 const bool isIntVal = de::inRange<int>(m_spec.inputs[inputNdx].type, TYPE_INT, TYPE_INT_VEC4);
888 const bool isUintVal = de::inRange<int>(m_spec.inputs[inputNdx].type, TYPE_UINT, TYPE_UINT_VEC4);
889 // \note Mediump interpolators are used for booleans, and highp for integers.
890 const Precision prec = isBoolVal ? PRECISION_MEDIUMP :
891 isIntVal || isUintVal ? PRECISION_HIGHP :
892 m_spec.precision;
893 inputPrecision[inputNdx] = getPrecisionName(prec);
894 }
895
896 // Attributes.
897 vtx << "layout(location = 0) in highp vec4 a_position;\n";
898 for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
899 vtx << "layout(location = " << 4 + inputNdx << ") in " << inputPrecision[inputNdx] << " vec4 a_in" << inputNdx
900 << ";\n";
901
902 // Color output.
903 frag << "layout(location = 0) out mediump vec4 o_color;\n";
904
905 if (m_isVertexCase)
906 {
907 vtx << "layout(location = 0) out mediump vec4 v_color;\n";
908 frag << "layout(location = 0) in mediump vec4 v_color;\n";
909 }
910 else
911 {
912 for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
913 {
914 vtx << "layout(location = " << inputNdx + 1 << ") out " << inputPrecision[inputNdx] << " vec4 v_in"
915 << inputNdx << ";\n";
916 frag << "layout(location = " << inputNdx + 1 << ") in " << inputPrecision[inputNdx] << " vec4 v_in"
917 << inputNdx << ";\n";
918 }
919 }
920
921 vtx << "\n";
922 vtx << "void main()\n";
923 vtx << "{\n";
924 vtx << " gl_Position = a_position;\n";
925
926 frag << "\n";
927 frag << "void main()\n";
928 frag << "{\n";
929
930 // Expression inputs.
931 const std::string prefix = m_isVertexCase ? "a_" : "v_";
932 for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
933 {
934 const DataType inType = m_spec.inputs[inputNdx].type;
935 const int inSize = getDataTypeScalarSize(inType);
936 const bool isInt = de::inRange<int>(inType, TYPE_INT, TYPE_INT_VEC4);
937 const bool isUint = de::inRange<int>(inType, TYPE_UINT, TYPE_UINT_VEC4);
938 const bool isBool = de::inRange<int>(inType, TYPE_BOOL, TYPE_BOOL_VEC4);
939 const char *typeName = getDataTypeName(inType);
940 const char *swizzle = s_inSwizzles[inputNdx][inSize - 1];
941
942 op << "\t";
943 if (precision && !isBool)
944 op << precision << " ";
945
946 op << typeName << " in" << inputNdx << " = ";
947
948 if (isBool)
949 {
950 if (inSize == 1)
951 op << "(";
952 else
953 op << "greaterThan(";
954 }
955 else if (isInt || isUint)
956 op << typeName << "(";
957
958 op << prefix << "in" << inputNdx << "." << swizzle;
959
960 if (isBool)
961 {
962 if (inSize == 1)
963 op << " > 0.0)";
964 else
965 op << ", vec" << inSize << "(0.0))";
966 }
967 else if (isInt || isUint)
968 op << ")";
969
970 op << ";\n";
971 }
972
973 // Result variable.
974 {
975 const char *outTypeName = getDataTypeName(m_spec.output);
976 const bool isBoolOut = de::inRange<int>(m_spec.output, TYPE_BOOL, TYPE_BOOL_VEC4);
977
978 op << "\t";
979 if (precision && !isBoolOut)
980 op << precision << " ";
981 op << outTypeName << " res = " << outTypeName << "(0.0);\n\n";
982 }
983
984 // Expression.
985 op << "\t" << m_shaderOp << "\n\n";
986
987 // Convert to color.
988 const bool isResFloatVec = de::inRange<int>(m_spec.output, TYPE_FLOAT, TYPE_FLOAT_VEC4);
989 const int outScalarSize = getDataTypeScalarSize(m_spec.output);
990
991 op << "\thighp vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n";
992 op << "\tcolor." << s_outSwizzles[outScalarSize - 1] << " = ";
993
994 if (!isResFloatVec && outScalarSize == 1)
995 op << "float(res)";
996 else if (!isResFloatVec)
997 op << "vec" << outScalarSize << "(res)";
998 else
999 op << "res";
1000
1001 op << ";\n";
1002
1003 // Scale & bias.
1004 const float resultScale = m_spec.resultScale;
1005 const float resultBias = m_spec.resultBias;
1006 if ((resultScale != 1.0f) || (resultBias != 0.0f))
1007 {
1008 op << "\tcolor = color";
1009 if (resultScale != 1.0f)
1010 op << " * " << twoValuedVec4(de::toString(resultScale), "1.0", s_outSwizzleChannelMasks[outScalarSize - 1]);
1011 if (resultBias != 0.0f)
1012 op << " + "
1013 << twoValuedVec4(de::floatToString(resultBias, 2), "0.0", s_outSwizzleChannelMasks[outScalarSize - 1]);
1014 op << ";\n";
1015 }
1016
1017 // ..
1018 if (m_isVertexCase)
1019 {
1020 vtx << " v_color = color;\n";
1021 frag << " o_color = v_color;\n";
1022 }
1023 else
1024 {
1025 for (int inputNdx = 0; inputNdx < m_spec.numInputs; inputNdx++)
1026 vtx << " v_in" << inputNdx << " = a_in" << inputNdx << ";\n";
1027 frag << " o_color = color;\n";
1028 }
1029
1030 vtx << "}\n";
1031 frag << "}\n";
1032
1033 m_vertShaderSource = vtx.str();
1034 m_fragShaderSource = frag.str();
1035 }
1036
~ShaderOperatorCase(void)1037 ShaderOperatorCase::~ShaderOperatorCase(void)
1038 {
1039 }
1040
1041 // Vector math functions.
1042 template <typename T>
nop(T f)1043 inline T nop(T f)
1044 {
1045 return f;
1046 }
1047
1048 template <typename T, int Size>
nop(const Vector<T,Size> & v)1049 Vector<T, Size> nop(const Vector<T, Size> &v)
1050 {
1051 return v;
1052 }
1053
1054 #define DECLARE_UNARY_GENTYPE_FUNCS(FUNC_NAME) \
1055 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1056 { \
1057 c.color.x() = FUNC_NAME(c.in[0].swizzle(2)).x(); \
1058 } \
1059 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1060 { \
1061 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1)); \
1062 } \
1063 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1064 { \
1065 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1)); \
1066 } \
1067 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1068 { \
1069 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); \
1070 }
1071
1072 #define DECLARE_BINARY_GENTYPE_FUNCS(FUNC_NAME) \
1073 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1074 { \
1075 c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0)).x(); \
1076 } \
1077 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1078 { \
1079 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); \
1080 } \
1081 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1082 { \
1083 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); \
1084 } \
1085 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1086 { \
1087 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); \
1088 }
1089
1090 #define DECLARE_TERNARY_GENTYPE_FUNCS(FUNC_NAME) \
1091 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1092 { \
1093 c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0), c.in[2].swizzle(1)).x(); \
1094 } \
1095 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1096 { \
1097 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0), c.in[2].swizzle(2, 1)); \
1098 } \
1099 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1100 { \
1101 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)); \
1102 } \
1103 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1104 { \
1105 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)); \
1106 }
1107
1108 #define DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME) \
1109 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1110 { \
1111 c.color.x() = FUNC_NAME(c.in[0].swizzle(2)); \
1112 } \
1113 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1114 { \
1115 c.color.x() = FUNC_NAME(c.in[0].swizzle(3, 1)); \
1116 } \
1117 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1118 { \
1119 c.color.x() = FUNC_NAME(c.in[0].swizzle(2, 0, 1)); \
1120 } \
1121 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1122 { \
1123 c.color.x() = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); \
1124 }
1125
1126 #define DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME) \
1127 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1128 { \
1129 c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0)); \
1130 } \
1131 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1132 { \
1133 c.color.x() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); \
1134 } \
1135 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1136 { \
1137 c.color.x() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); \
1138 } \
1139 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1140 { \
1141 c.color.x() = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); \
1142 }
1143
1144 #define DECLARE_BINARY_BOOL_FUNCS(FUNC_NAME) \
1145 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1146 { \
1147 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); \
1148 }
1149
1150 #define DECLARE_UNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME) \
1151 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1152 { \
1153 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f); \
1154 } \
1155 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
1156 { \
1157 c.color.yz() = FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); \
1158 } \
1159 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
1160 { \
1161 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); \
1162 } \
1163 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
1164 { \
1165 c.color = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f))).asFloat(); \
1166 }
1167
1168 #define DECLARE_TERNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME) \
1169 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1170 { \
1171 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f, c.in[2].y() > 0.0f); \
1172 } \
1173 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
1174 { \
1175 c.color.yz() = \
1176 FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)), greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f)), \
1177 greaterThan(c.in[2].swizzle(2, 1), Vec2(0.0f))) \
1178 .asFloat(); \
1179 } \
1180 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
1181 { \
1182 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)), \
1183 greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f)), \
1184 greaterThan(c.in[2].swizzle(3, 1, 2), Vec3(0.0f))) \
1185 .asFloat(); \
1186 } \
1187 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
1188 { \
1189 c.color = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), \
1190 greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f)), \
1191 greaterThan(c.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f))) \
1192 .asFloat(); \
1193 }
1194
1195 #define DECLARE_UNARY_INT_GENTYPE_FUNCS(FUNC_NAME) \
1196 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1197 { \
1198 c.color.x() = (float)FUNC_NAME((int)c.in[0].z()); \
1199 } \
1200 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1201 { \
1202 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt()).asFloat(); \
1203 } \
1204 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1205 { \
1206 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt()).asFloat(); \
1207 } \
1208 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1209 { \
1210 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt()).asFloat(); \
1211 }
1212
1213 #define DECLARE_BINARY_INT_GENTYPE_FUNCS(FUNC_NAME) \
1214 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1215 { \
1216 c.color.x() = (float)FUNC_NAME((int)c.in[0].z(), (int)c.in[1].x()); \
1217 } \
1218 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1219 { \
1220 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1221 } \
1222 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1223 { \
1224 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1225 } \
1226 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1227 { \
1228 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1229 }
1230
1231 #define DECLARE_UNARY_UINT_GENTYPE_FUNCS(FUNC_NAME) \
1232 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1233 { \
1234 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z()); \
1235 } \
1236 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1237 { \
1238 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint()).asFloat(); \
1239 } \
1240 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1241 { \
1242 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint()).asFloat(); \
1243 } \
1244 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1245 { \
1246 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint()).asFloat(); \
1247 }
1248
1249 #define DECLARE_BINARY_UINT_GENTYPE_FUNCS(FUNC_NAME) \
1250 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1251 { \
1252 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x()); \
1253 } \
1254 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1255 { \
1256 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
1257 } \
1258 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1259 { \
1260 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
1261 } \
1262 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1263 { \
1264 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
1265 }
1266
1267 #define DECLARE_TERNARY_INT_GENTYPE_FUNCS(FUNC_NAME) \
1268 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1269 { \
1270 c.color.x() = (float)FUNC_NAME((int)c.in[0].z(), (int)c.in[1].x(), (int)c.in[2].y()); \
1271 } \
1272 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1273 { \
1274 c.color.yz() = \
1275 FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), c.in[1].swizzle(1, 0).asInt(), c.in[2].swizzle(2, 1).asInt()) \
1276 .asFloat(); \
1277 } \
1278 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1279 { \
1280 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), c.in[1].swizzle(1, 2, 0).asInt(), \
1281 c.in[2].swizzle(3, 1, 2).asInt()) \
1282 .asFloat(); \
1283 } \
1284 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1285 { \
1286 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), c.in[1].swizzle(3, 2, 1, 0).asInt(), \
1287 c.in[2].swizzle(0, 3, 2, 1).asInt()) \
1288 .asFloat(); \
1289 }
1290
1291 #define DECLARE_TERNARY_UINT_GENTYPE_FUNCS(FUNC_NAME) \
1292 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1293 { \
1294 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()); \
1295 } \
1296 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1297 { \
1298 c.color.yz() = \
1299 FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint(), c.in[2].swizzle(2, 1).asUint()) \
1300 .asFloat(); \
1301 } \
1302 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1303 { \
1304 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint(), \
1305 c.in[2].swizzle(3, 1, 2).asUint()) \
1306 .asFloat(); \
1307 } \
1308 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1309 { \
1310 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint(), \
1311 c.in[2].swizzle(0, 3, 2, 1).asUint()) \
1312 .asFloat(); \
1313 }
1314
1315 #define DECLARE_VEC_FLOAT_FUNCS(FUNC_NAME) \
1316 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1317 { \
1318 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].x()); \
1319 } \
1320 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1321 { \
1322 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].x()); \
1323 } \
1324 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1325 { \
1326 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].x()); \
1327 }
1328
1329 #define DECLARE_VEC_FLOAT_FLOAT_FUNCS(FUNC_NAME) \
1330 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1331 { \
1332 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].x(), c.in[2].y()); \
1333 } \
1334 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1335 { \
1336 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].x(), c.in[2].y()); \
1337 } \
1338 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1339 { \
1340 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].x(), c.in[2].y()); \
1341 }
1342
1343 #define DECLARE_VEC_VEC_FLOAT_FUNCS(FUNC_NAME) \
1344 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1345 { \
1346 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0), c.in[2].y()); \
1347 } \
1348 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1349 { \
1350 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0), c.in[2].y()); \
1351 } \
1352 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1353 { \
1354 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0), c.in[2].y()); \
1355 }
1356
1357 #define DECLARE_FLOAT_FLOAT_VEC_FUNCS(FUNC_NAME) \
1358 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1359 { \
1360 c.color.yz() = FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(2, 1)); \
1361 } \
1362 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1363 { \
1364 c.color.xyz() = FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(3, 1, 2)); \
1365 } \
1366 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1367 { \
1368 c.color = FUNC_NAME(c.in[0].z(), c.in[1].x(), c.in[2].swizzle(0, 3, 2, 1)); \
1369 }
1370
1371 #define DECLARE_FLOAT_VEC_FUNCS(FUNC_NAME) \
1372 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1373 { \
1374 c.color.yz() = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(1, 0)); \
1375 } \
1376 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1377 { \
1378 c.color.xyz() = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(1, 2, 0)); \
1379 } \
1380 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1381 { \
1382 c.color = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(3, 2, 1, 0)); \
1383 }
1384
1385 #define DECLARE_IVEC_INT_FUNCS(FUNC_NAME) \
1386 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1387 { \
1388 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), (int)c.in[1].x()).asFloat(); \
1389 } \
1390 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1391 { \
1392 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), (int)c.in[1].x()).asFloat(); \
1393 } \
1394 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1395 { \
1396 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), (int)c.in[1].x()).asFloat(); \
1397 }
1398
1399 #define DECLARE_IVEC_INT_INT_FUNCS(FUNC_NAME) \
1400 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1401 { \
1402 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), (int)c.in[1].x(), (int)c.in[2].y()).asFloat(); \
1403 } \
1404 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1405 { \
1406 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), (int)c.in[1].x(), (int)c.in[2].y()).asFloat(); \
1407 } \
1408 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1409 { \
1410 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), (int)c.in[1].x(), (int)c.in[2].y()).asFloat(); \
1411 }
1412
1413 #define DECLARE_INT_IVEC_FUNCS(FUNC_NAME) \
1414 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1415 { \
1416 c.color.yz() = FUNC_NAME((int)c.in[0].z(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1417 } \
1418 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1419 { \
1420 c.color.xyz() = FUNC_NAME((int)c.in[0].z(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1421 } \
1422 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1423 { \
1424 c.color = FUNC_NAME((int)c.in[0].z(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1425 }
1426
1427 #define DECLARE_UVEC_UINT_FUNCS(FUNC_NAME) \
1428 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1429 { \
1430 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), (uint32_t)c.in[1].x()).asFloat(); \
1431 } \
1432 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1433 { \
1434 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), (uint32_t)c.in[1].x()).asFloat(); \
1435 } \
1436 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1437 { \
1438 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), (uint32_t)c.in[1].x()).asFloat(); \
1439 }
1440
1441 #define DECLARE_UVEC_UINT_UINT_FUNCS(FUNC_NAME) \
1442 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1443 { \
1444 c.color.yz() = \
1445 FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()).asFloat(); \
1446 } \
1447 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1448 { \
1449 c.color.xyz() = \
1450 FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()).asFloat(); \
1451 } \
1452 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1453 { \
1454 c.color = \
1455 FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y()).asFloat(); \
1456 }
1457
1458 #define DECLARE_UINT_UVEC_FUNCS(FUNC_NAME) \
1459 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1460 { \
1461 c.color.yz() = FUNC_NAME((uint32_t)c.in[0].z(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
1462 } \
1463 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1464 { \
1465 c.color.xyz() = FUNC_NAME((uint32_t)c.in[0].z(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
1466 } \
1467 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1468 { \
1469 c.color = FUNC_NAME((uint32_t)c.in[0].z(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
1470 }
1471
1472 #define DECLARE_BINARY_INT_VEC_FUNCS(FUNC_NAME) \
1473 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1474 { \
1475 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1476 } \
1477 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1478 { \
1479 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1480 } \
1481 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1482 { \
1483 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1484 }
1485
1486 #define DECLARE_BINARY_UINT_VEC_FUNCS(FUNC_NAME) \
1487 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1488 { \
1489 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
1490 } \
1491 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1492 { \
1493 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
1494 } \
1495 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1496 { \
1497 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
1498 }
1499
1500 #define DECLARE_UINT_INT_GENTYPE_FUNCS(FUNC_NAME) \
1501 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1502 { \
1503 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (int)c.in[1].x()); \
1504 } \
1505 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1506 { \
1507 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asInt()).asFloat(); \
1508 } \
1509 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1510 { \
1511 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asInt()).asFloat(); \
1512 } \
1513 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1514 { \
1515 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asInt()).asFloat(); \
1516 }
1517
1518 #define DECLARE_UVEC_INT_FUNCS(FUNC_NAME) \
1519 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1520 { \
1521 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), (int)c.in[1].x()).asFloat(); \
1522 } \
1523 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1524 { \
1525 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), (int)c.in[1].x()).asFloat(); \
1526 } \
1527 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1528 { \
1529 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), (int)c.in[1].x()).asFloat(); \
1530 }
1531
1532 // Operators.
1533
1534 DECLARE_UNARY_GENTYPE_FUNCS(nop)
DECLARE_UNARY_GENTYPE_FUNCS(negate)1535 DECLARE_UNARY_GENTYPE_FUNCS(negate)
1536 DECLARE_UNARY_GENTYPE_FUNCS(addOne)
1537 DECLARE_UNARY_GENTYPE_FUNCS(subOne)
1538 DECLARE_BINARY_GENTYPE_FUNCS(add)
1539 DECLARE_BINARY_GENTYPE_FUNCS(sub)
1540 DECLARE_BINARY_GENTYPE_FUNCS(mul)
1541 DECLARE_BINARY_GENTYPE_FUNCS(div)
1542
1543 void eval_selection_float(ShaderEvalContext &c)
1544 {
1545 c.color.x() = selection(c.in[0].z() > 0.0f, c.in[1].x(), c.in[2].y());
1546 }
eval_selection_vec2(ShaderEvalContext & c)1547 void eval_selection_vec2(ShaderEvalContext &c)
1548 {
1549 c.color.yz() = selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 0), c.in[2].swizzle(2, 1));
1550 }
eval_selection_vec3(ShaderEvalContext & c)1551 void eval_selection_vec3(ShaderEvalContext &c)
1552 {
1553 c.color.xyz() = selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 2, 0), c.in[2].swizzle(3, 1, 2));
1554 }
eval_selection_vec4(ShaderEvalContext & c)1555 void eval_selection_vec4(ShaderEvalContext &c)
1556 {
1557 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));
1558 }
1559
1560 DECLARE_UNARY_INT_GENTYPE_FUNCS(nop)
DECLARE_UNARY_INT_GENTYPE_FUNCS(negate)1561 DECLARE_UNARY_INT_GENTYPE_FUNCS(negate)
1562 DECLARE_UNARY_INT_GENTYPE_FUNCS(addOne)
1563 DECLARE_UNARY_INT_GENTYPE_FUNCS(subOne)
1564 DECLARE_UNARY_INT_GENTYPE_FUNCS(bitwiseNot)
1565 DECLARE_BINARY_INT_GENTYPE_FUNCS(add)
1566 DECLARE_BINARY_INT_GENTYPE_FUNCS(sub)
1567 DECLARE_BINARY_INT_GENTYPE_FUNCS(mul)
1568 DECLARE_BINARY_INT_GENTYPE_FUNCS(div)
1569 DECLARE_BINARY_INT_GENTYPE_FUNCS(mod)
1570 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseAnd)
1571 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseOr)
1572 DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseXor)
1573
1574 void eval_leftShift_int(ShaderEvalContext &c)
1575 {
1576 c.color.x() = (float)leftShift((int)c.in[0].z(), (int)c.in[1].x());
1577 }
DECLARE_BINARY_INT_VEC_FUNCS(leftShift)1578 DECLARE_BINARY_INT_VEC_FUNCS(leftShift)
1579 void eval_rightShift_int(ShaderEvalContext &c)
1580 {
1581 c.color.x() = (float)rightShift((int)c.in[0].z(), (int)c.in[1].x());
1582 }
1583 DECLARE_BINARY_INT_VEC_FUNCS(rightShift)
DECLARE_IVEC_INT_FUNCS(leftShiftVecScalar)1584 DECLARE_IVEC_INT_FUNCS(leftShiftVecScalar)
1585 DECLARE_IVEC_INT_FUNCS(rightShiftVecScalar)
1586
1587 void eval_selection_int(ShaderEvalContext &c)
1588 {
1589 c.color.x() = (float)selection(c.in[0].z() > 0.0f, (int)c.in[1].x(), (int)c.in[2].y());
1590 }
eval_selection_ivec2(ShaderEvalContext & c)1591 void eval_selection_ivec2(ShaderEvalContext &c)
1592 {
1593 c.color.yz() =
1594 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 0).asInt(), c.in[2].swizzle(2, 1).asInt()).asFloat();
1595 }
eval_selection_ivec3(ShaderEvalContext & c)1596 void eval_selection_ivec3(ShaderEvalContext &c)
1597 {
1598 c.color.xyz() =
1599 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 2, 0).asInt(), c.in[2].swizzle(3, 1, 2).asInt()).asFloat();
1600 }
eval_selection_ivec4(ShaderEvalContext & c)1601 void eval_selection_ivec4(ShaderEvalContext &c)
1602 {
1603 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())
1604 .asFloat();
1605 }
1606
1607 DECLARE_UNARY_UINT_GENTYPE_FUNCS(nop)
DECLARE_UNARY_UINT_GENTYPE_FUNCS(negate)1608 DECLARE_UNARY_UINT_GENTYPE_FUNCS(negate)
1609 DECLARE_UNARY_UINT_GENTYPE_FUNCS(bitwiseNot)
1610 DECLARE_UNARY_UINT_GENTYPE_FUNCS(addOne)
1611 DECLARE_UNARY_UINT_GENTYPE_FUNCS(subOne)
1612 DECLARE_BINARY_UINT_GENTYPE_FUNCS(add)
1613 DECLARE_BINARY_UINT_GENTYPE_FUNCS(sub)
1614 DECLARE_BINARY_UINT_GENTYPE_FUNCS(mul)
1615 DECLARE_BINARY_UINT_GENTYPE_FUNCS(div)
1616 DECLARE_BINARY_UINT_GENTYPE_FUNCS(mod)
1617 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseAnd)
1618 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseOr)
1619 DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseXor)
1620
1621 DECLARE_UINT_INT_GENTYPE_FUNCS(leftShift)
1622 DECLARE_UINT_INT_GENTYPE_FUNCS(rightShift)
1623 DECLARE_UVEC_INT_FUNCS(leftShiftVecScalar)
1624 DECLARE_UVEC_INT_FUNCS(rightShiftVecScalar)
1625
1626 void eval_selection_uint(ShaderEvalContext &c)
1627 {
1628 c.color.x() = (float)selection(c.in[0].z() > 0.0f, (uint32_t)c.in[1].x(), (uint32_t)c.in[2].y());
1629 }
eval_selection_uvec2(ShaderEvalContext & c)1630 void eval_selection_uvec2(ShaderEvalContext &c)
1631 {
1632 c.color.yz() =
1633 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 0).asUint(), c.in[2].swizzle(2, 1).asUint()).asFloat();
1634 }
eval_selection_uvec3(ShaderEvalContext & c)1635 void eval_selection_uvec3(ShaderEvalContext &c)
1636 {
1637 c.color.xyz() =
1638 selection(c.in[0].z() > 0.0f, c.in[1].swizzle(1, 2, 0).asUint(), c.in[2].swizzle(3, 1, 2).asUint()).asFloat();
1639 }
eval_selection_uvec4(ShaderEvalContext & c)1640 void eval_selection_uvec4(ShaderEvalContext &c)
1641 {
1642 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())
1643 .asFloat();
1644 }
1645
1646 DECLARE_UNARY_BOOL_GENTYPE_FUNCS(boolNot)
DECLARE_BINARY_BOOL_FUNCS(logicalAnd)1647 DECLARE_BINARY_BOOL_FUNCS(logicalAnd)
1648 DECLARE_BINARY_BOOL_FUNCS(logicalOr)
1649 DECLARE_BINARY_BOOL_FUNCS(logicalXor)
1650
1651 void eval_selection_bool(ShaderEvalContext &c)
1652 {
1653 c.color.x() = (float)selection(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f, c.in[2].y() > 0.0f);
1654 }
eval_selection_bvec2(ShaderEvalContext & c)1655 void eval_selection_bvec2(ShaderEvalContext &c)
1656 {
1657 c.color.yz() = selection(c.in[0].z() > 0.0f, greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f, 0.0f)),
1658 greaterThan(c.in[2].swizzle(2, 1), Vec2(0.0f, 0.0f)))
1659 .asFloat();
1660 }
eval_selection_bvec3(ShaderEvalContext & c)1661 void eval_selection_bvec3(ShaderEvalContext &c)
1662 {
1663 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)),
1664 greaterThan(c.in[2].swizzle(3, 1, 2), Vec3(0.0f, 0.0f, 0.0f)))
1665 .asFloat();
1666 }
eval_selection_bvec4(ShaderEvalContext & c)1667 void eval_selection_bvec4(ShaderEvalContext &c)
1668 {
1669 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)),
1670 greaterThan(c.in[2].swizzle(0, 3, 2, 1), Vec4(0.0f, 0.0f, 0.0f, 0.0f)))
1671 .asFloat();
1672 }
1673
1674 DECLARE_VEC_FLOAT_FUNCS(addVecScalar)
1675 DECLARE_VEC_FLOAT_FUNCS(subVecScalar)
1676 DECLARE_VEC_FLOAT_FUNCS(mulVecScalar)
1677 DECLARE_VEC_FLOAT_FUNCS(divVecScalar)
1678
1679 DECLARE_FLOAT_VEC_FUNCS(addScalarVec)
1680 DECLARE_FLOAT_VEC_FUNCS(subScalarVec)
1681 DECLARE_FLOAT_VEC_FUNCS(mulScalarVec)
1682 DECLARE_FLOAT_VEC_FUNCS(divScalarVec)
1683
1684 DECLARE_IVEC_INT_FUNCS(addVecScalar)
1685 DECLARE_IVEC_INT_FUNCS(subVecScalar)
1686 DECLARE_IVEC_INT_FUNCS(mulVecScalar)
1687 DECLARE_IVEC_INT_FUNCS(divVecScalar)
1688 DECLARE_IVEC_INT_FUNCS(modVecScalar)
1689 DECLARE_IVEC_INT_FUNCS(bitwiseAndVecScalar)
1690 DECLARE_IVEC_INT_FUNCS(bitwiseOrVecScalar)
1691 DECLARE_IVEC_INT_FUNCS(bitwiseXorVecScalar)
1692
1693 DECLARE_INT_IVEC_FUNCS(addScalarVec)
1694 DECLARE_INT_IVEC_FUNCS(subScalarVec)
1695 DECLARE_INT_IVEC_FUNCS(mulScalarVec)
1696 DECLARE_INT_IVEC_FUNCS(divScalarVec)
1697 DECLARE_INT_IVEC_FUNCS(modScalarVec)
1698 DECLARE_INT_IVEC_FUNCS(bitwiseAndScalarVec)
1699 DECLARE_INT_IVEC_FUNCS(bitwiseOrScalarVec)
1700 DECLARE_INT_IVEC_FUNCS(bitwiseXorScalarVec)
1701
1702 DECLARE_UVEC_UINT_FUNCS(addVecScalar)
1703 DECLARE_UVEC_UINT_FUNCS(subVecScalar)
1704 DECLARE_UVEC_UINT_FUNCS(mulVecScalar)
1705 DECLARE_UVEC_UINT_FUNCS(divVecScalar)
1706 DECLARE_UVEC_UINT_FUNCS(modVecScalar)
1707 DECLARE_UVEC_UINT_FUNCS(bitwiseAndVecScalar)
1708 DECLARE_UVEC_UINT_FUNCS(bitwiseOrVecScalar)
1709 DECLARE_UVEC_UINT_FUNCS(bitwiseXorVecScalar)
1710
1711 DECLARE_UINT_UVEC_FUNCS(addScalarVec)
1712 DECLARE_UINT_UVEC_FUNCS(subScalarVec)
1713 DECLARE_UINT_UVEC_FUNCS(mulScalarVec)
1714 DECLARE_UINT_UVEC_FUNCS(divScalarVec)
1715 DECLARE_UINT_UVEC_FUNCS(modScalarVec)
1716 DECLARE_UINT_UVEC_FUNCS(bitwiseAndScalarVec)
1717 DECLARE_UINT_UVEC_FUNCS(bitwiseOrScalarVec)
1718 DECLARE_UINT_UVEC_FUNCS(bitwiseXorScalarVec)
1719
1720 // Built-in functions.
1721 DECLARE_BINARY_INT_GENTYPE_FUNCS(min)
1722 DECLARE_IVEC_INT_FUNCS(minVecScalar)
1723 DECLARE_BINARY_UINT_GENTYPE_FUNCS(min)
1724 DECLARE_UVEC_UINT_FUNCS(minVecScalar)
1725 DECLARE_BINARY_INT_GENTYPE_FUNCS(max)
1726 DECLARE_IVEC_INT_FUNCS(maxVecScalar)
1727 DECLARE_BINARY_UINT_GENTYPE_FUNCS(max)
1728 DECLARE_UVEC_UINT_FUNCS(maxVecScalar)
1729 DECLARE_TERNARY_INT_GENTYPE_FUNCS(clamp)
1730 DECLARE_IVEC_INT_INT_FUNCS(clampVecScalarScalar)
1731 DECLARE_TERNARY_UINT_GENTYPE_FUNCS(clamp)
1732 DECLARE_UVEC_UINT_UINT_FUNCS(clampVecScalarScalar)
1733
1734 // Compare functions.
1735
1736 #define DECLARE_FLOAT_COMPARE_FUNCS(FUNC_NAME) \
1737 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1738 { \
1739 c.color.x() = (float)FUNC_NAME(c.in[0].z(), c.in[1].x()); \
1740 } \
1741 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1742 { \
1743 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); \
1744 } \
1745 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1746 { \
1747 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); \
1748 } \
1749 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1750 { \
1751 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)); \
1752 }
1753
1754 #define DECLARE_FLOAT_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1755 void eval_##FUNC_NAME##_float(ShaderEvalContext &c) \
1756 { \
1757 c.color.x() = (float)FUNC_NAME(c.in[0].z(), c.in[1].x()); \
1758 } \
1759 DECLARE_FLOAT_VEC_CWISE_COMPARE_FUNCS(FUNC_NAME)
1760
1761 #define DECLARE_FLOAT_VEC_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1762 void eval_##FUNC_NAME##_vec2(ShaderEvalContext &c) \
1763 { \
1764 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)).asFloat(); \
1765 } \
1766 void eval_##FUNC_NAME##_vec3(ShaderEvalContext &c) \
1767 { \
1768 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)).asFloat(); \
1769 } \
1770 void eval_##FUNC_NAME##_vec4(ShaderEvalContext &c) \
1771 { \
1772 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].swizzle(3, 2, 1, 0)).asFloat(); \
1773 }
1774
1775 #define DECLARE_INT_COMPARE_FUNCS(FUNC_NAME) \
1776 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1777 { \
1778 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); \
1779 } \
1780 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1781 { \
1782 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].swizzle(3, 1)), chopToInt(c.in[1].swizzle(1, 0))); \
1783 } \
1784 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1785 { \
1786 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].swizzle(2, 0, 1)), chopToInt(c.in[1].swizzle(1, 2, 0))); \
1787 } \
1788 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1789 { \
1790 c.color.x() = \
1791 (float)FUNC_NAME(chopToInt(c.in[0].swizzle(1, 2, 3, 0)), chopToInt(c.in[1].swizzle(3, 2, 1, 0))); \
1792 }
1793
1794 #define DECLARE_INT_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1795 void eval_##FUNC_NAME##_int(ShaderEvalContext &c) \
1796 { \
1797 c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); \
1798 } \
1799 DECLARE_INT_VEC_CWISE_COMPARE_FUNCS(FUNC_NAME)
1800
1801 #define DECLARE_INT_VEC_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1802 void eval_##FUNC_NAME##_ivec2(ShaderEvalContext &c) \
1803 { \
1804 c.color.yz() = FUNC_NAME(chopToInt(c.in[0].swizzle(3, 1)), chopToInt(c.in[1].swizzle(1, 0))).asFloat(); \
1805 } \
1806 void eval_##FUNC_NAME##_ivec3(ShaderEvalContext &c) \
1807 { \
1808 c.color.xyz() = FUNC_NAME(chopToInt(c.in[0].swizzle(2, 0, 1)), chopToInt(c.in[1].swizzle(1, 2, 0))).asFloat(); \
1809 } \
1810 void eval_##FUNC_NAME##_ivec4(ShaderEvalContext &c) \
1811 { \
1812 c.color = FUNC_NAME(chopToInt(c.in[0].swizzle(1, 2, 3, 0)), chopToInt(c.in[1].swizzle(3, 2, 1, 0))).asFloat(); \
1813 }
1814
1815 #define DECLARE_UINT_COMPARE_FUNCS(FUNC_NAME) \
1816 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1817 { \
1818 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x()); \
1819 } \
1820 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1821 { \
1822 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()); \
1823 } \
1824 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1825 { \
1826 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()); \
1827 } \
1828 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1829 { \
1830 c.color.x() = (float)FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()); \
1831 }
1832
1833 #define DECLARE_UINT_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1834 DECLARE_UINT_SCALAR_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1835 void eval_##FUNC_NAME##_uvec2(ShaderEvalContext &c) \
1836 { \
1837 c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asUint(), c.in[1].swizzle(1, 0).asUint()).asFloat(); \
1838 } \
1839 void eval_##FUNC_NAME##_uvec3(ShaderEvalContext &c) \
1840 { \
1841 c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asUint(), c.in[1].swizzle(1, 2, 0).asUint()).asFloat(); \
1842 } \
1843 void eval_##FUNC_NAME##_uvec4(ShaderEvalContext &c) \
1844 { \
1845 c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asUint(), c.in[1].swizzle(3, 2, 1, 0).asUint()).asFloat(); \
1846 }
1847
1848 #define DECLARE_UINT_SCALAR_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1849 void eval_##FUNC_NAME##_uint(ShaderEvalContext &c) \
1850 { \
1851 c.color.x() = (float)FUNC_NAME((uint32_t)c.in[0].z(), (uint32_t)c.in[1].x()); \
1852 }
1853
1854 #define DECLARE_BOOL_COMPARE_FUNCS(FUNC_NAME) \
1855 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1856 { \
1857 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); \
1858 } \
1859 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
1860 { \
1861 c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)), \
1862 greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f))); \
1863 } \
1864 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
1865 { \
1866 c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)), \
1867 greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f))); \
1868 } \
1869 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
1870 { \
1871 c.color.x() = (float)FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), \
1872 greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f))); \
1873 }
1874
1875 #define DECLARE_BOOL_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1876 void eval_##FUNC_NAME##_bool(ShaderEvalContext &c) \
1877 { \
1878 c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f, c.in[1].x() > 0.0f); \
1879 } \
1880 DECLARE_BOOL_VEC_CWISE_COMPARE_FUNCS(FUNC_NAME)
1881
1882 #define DECLARE_BOOL_VEC_CWISE_COMPARE_FUNCS(FUNC_NAME) \
1883 void eval_##FUNC_NAME##_bvec2(ShaderEvalContext &c) \
1884 { \
1885 c.color.yz() = \
1886 FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)), greaterThan(c.in[1].swizzle(1, 0), Vec2(0.0f))) \
1887 .asFloat(); \
1888 } \
1889 void eval_##FUNC_NAME##_bvec3(ShaderEvalContext &c) \
1890 { \
1891 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)), \
1892 greaterThan(c.in[1].swizzle(1, 2, 0), Vec3(0.0f))) \
1893 .asFloat(); \
1894 } \
1895 void eval_##FUNC_NAME##_bvec4(ShaderEvalContext &c) \
1896 { \
1897 c.color = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)), \
1898 greaterThan(c.in[1].swizzle(3, 2, 1, 0), Vec4(0.0f))) \
1899 .asFloat(); \
1900 }
1901
1902 DECLARE_FLOAT_COMPARE_FUNCS(allEqual)
1903 DECLARE_FLOAT_COMPARE_FUNCS(anyNotEqual)
1904 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThan)
1905 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThanEqual)
1906 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThan)
1907 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThanEqual)
1908 DECLARE_FLOAT_VEC_CWISE_COMPARE_FUNCS(equal)
1909 DECLARE_FLOAT_VEC_CWISE_COMPARE_FUNCS(notEqual)
1910
1911 DECLARE_INT_COMPARE_FUNCS(allEqual)
1912 DECLARE_INT_COMPARE_FUNCS(anyNotEqual)
1913 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThan)
1914 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThanEqual)
1915 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThan)
1916 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThanEqual)
1917 DECLARE_INT_VEC_CWISE_COMPARE_FUNCS(equal)
1918 DECLARE_INT_VEC_CWISE_COMPARE_FUNCS(notEqual)
1919
1920 DECLARE_UINT_COMPARE_FUNCS(allEqual)
1921 DECLARE_UINT_COMPARE_FUNCS(anyNotEqual)
1922 DECLARE_UINT_SCALAR_CWISE_COMPARE_FUNCS(lessThan)
1923 DECLARE_UINT_SCALAR_CWISE_COMPARE_FUNCS(lessThanEqual)
1924 DECLARE_UINT_SCALAR_CWISE_COMPARE_FUNCS(greaterThan)
1925 DECLARE_UINT_SCALAR_CWISE_COMPARE_FUNCS(greaterThanEqual)
1926
1927 DECLARE_BOOL_COMPARE_FUNCS(allEqual)
1928 DECLARE_BOOL_COMPARE_FUNCS(anyNotEqual)
1929 DECLARE_BOOL_VEC_CWISE_COMPARE_FUNCS(equal)
1930 DECLARE_BOOL_VEC_CWISE_COMPARE_FUNCS(notEqual)
1931
1932 // Boolean functions.
1933
1934 #define DECLARE_UNARY_SCALAR_BVEC_FUNCS(GLSL_NAME, FUNC_NAME) \
1935 void eval_##GLSL_NAME##_bvec2(ShaderEvalContext &c) \
1936 { \
1937 c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)))); \
1938 } \
1939 void eval_##GLSL_NAME##_bvec3(ShaderEvalContext &c) \
1940 { \
1941 c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)))); \
1942 } \
1943 void eval_##GLSL_NAME##_bvec4(ShaderEvalContext &c) \
1944 { \
1945 c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f)))); \
1946 }
1947
1948 #define DECLARE_UNARY_BVEC_BVEC_FUNCS(GLSL_NAME, FUNC_NAME) \
1949 void eval_##GLSL_NAME##_bvec2(ShaderEvalContext &c) \
1950 { \
1951 c.color.yz() = FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); \
1952 } \
1953 void eval_##GLSL_NAME##_bvec3(ShaderEvalContext &c) \
1954 { \
1955 c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); \
1956 } \
1957 void eval_##GLSL_NAME##_bvec4(ShaderEvalContext &c) \
1958 { \
1959 c.color.xyzw() = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f))).asFloat(); \
1960 }
1961
1962 DECLARE_UNARY_SCALAR_BVEC_FUNCS(any, boolAny)
1963 DECLARE_UNARY_SCALAR_BVEC_FUNCS(all, boolAll)
1964
1965 // ShaderOperatorTests.
1966
1967 class ShaderOperatorTests : public tcu::TestCaseGroup
1968 {
1969 public:
1970 ShaderOperatorTests(tcu::TestContext &context);
1971 virtual ~ShaderOperatorTests(void);
1972
1973 virtual void init(void);
1974
1975 private:
1976 ShaderOperatorTests(const ShaderOperatorTests &); // not allowed!
1977 ShaderOperatorTests &operator=(const ShaderOperatorTests &); // not allowed!
1978 };
1979
ShaderOperatorTests(tcu::TestContext & testCtx)1980 ShaderOperatorTests::ShaderOperatorTests(tcu::TestContext &testCtx) : TestCaseGroup(testCtx, "operator")
1981 {
1982 }
1983
~ShaderOperatorTests(void)1984 ShaderOperatorTests::~ShaderOperatorTests(void)
1985 {
1986 }
1987
init(void)1988 void ShaderOperatorTests::init(void)
1989 {
1990 #define BOOL_FUNCS(FUNC_NAME) eval_##FUNC_NAME##_bool, DE_NULL, DE_NULL, DE_NULL
1991
1992 #define FLOAT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4
1993 #define INT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4
1994 #define UINT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_uvec2, eval_##FUNC_NAME##_uvec3, eval_##FUNC_NAME##_uvec4
1995 #define BOOL_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4
1996
1997 #define FLOAT_GENTYPE_FUNCS(FUNC_NAME) \
1998 eval_##FUNC_NAME##_float, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4
1999 #define INT_GENTYPE_FUNCS(FUNC_NAME) \
2000 eval_##FUNC_NAME##_int, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4
2001 #define UINT_GENTYPE_FUNCS(FUNC_NAME) \
2002 eval_##FUNC_NAME##_uint, eval_##FUNC_NAME##_uvec2, eval_##FUNC_NAME##_uvec3, eval_##FUNC_NAME##_uvec4
2003 #define BOOL_GENTYPE_FUNCS(FUNC_NAME) \
2004 eval_##FUNC_NAME##_bool, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4
2005
2006 // Shorthands.
2007 Value notUsed = Value(VALUE_NONE, 0.0f, 0.0f);
2008
2009 std::vector<BuiltinFuncGroup> funcInfoGroups;
2010
2011 // Unary operators.
2012 funcInfoGroups.push_back(
2013 BuiltinFuncGroup("unary_operator", "Unary operator tests")
2014 << BuiltinOperInfo("minus", "-", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL,
2015 FLOAT_GENTYPE_FUNCS(negate))
2016 << BuiltinOperInfo("minus", "-", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL,
2017 INT_GENTYPE_FUNCS(negate))
2018 << BuiltinOperInfo("minus", "-", UGT, Value(UGT, 0.0f, 4e9f), notUsed, notUsed, 2e-10f, 0.0f, PRECMASK_HIGHP,
2019 UINT_GENTYPE_FUNCS(negate))
2020 << BuiltinOperInfo("not", "!", B, Value(B, -1.0f, 1.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_NA,
2021 eval_boolNot_bool, DE_NULL, DE_NULL, DE_NULL)
2022 << BuiltinOperInfo("bitwise_not", "~", IGT, Value(IGT, -1e5f, 1e5f), notUsed, notUsed, 5e-5f, 0.5f,
2023 PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseNot))
2024 << BuiltinOperInfo("bitwise_not", "~", UGT, Value(UGT, 0.0f, 2e9f), notUsed, notUsed, 2e-10f, 0.0f,
2025 PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseNot))
2026
2027 // Pre/post incr/decr side effect cases.
2028 << BuiltinSideEffOperInfo("pre_increment_effect", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2029 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne))
2030 << BuiltinSideEffOperInfo("pre_increment_effect", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed, 0.1f,
2031 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne))
2032 << BuiltinSideEffOperInfo("pre_increment_effect", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed, 0.1f,
2033 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(addOne))
2034 << BuiltinSideEffOperInfo("pre_decrement_effect", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2035 1.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne))
2036 << BuiltinSideEffOperInfo("pre_decrement_effect", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed, 0.1f,
2037 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne))
2038 << BuiltinSideEffOperInfo("pre_decrement_effect", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed, 0.1f,
2039 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(subOne))
2040 << BuiltinPostSideEffOperInfo("post_increment_effect", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2041 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne))
2042 << BuiltinPostSideEffOperInfo("post_increment_effect", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed,
2043 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne))
2044 << BuiltinPostSideEffOperInfo("post_increment_effect", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed,
2045 0.1f, 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(addOne))
2046 << BuiltinPostSideEffOperInfo("post_decrement_effect", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f,
2047 1.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne))
2048 << BuiltinPostSideEffOperInfo("post_decrement_effect", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed,
2049 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne))
2050 << BuiltinPostSideEffOperInfo("post_decrement_effect", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed,
2051 0.1f, 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(subOne))
2052
2053 // Pre/post incr/decr result cases.
2054 << BuiltinOperInfo("pre_increment_result", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.0f,
2055 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne))
2056 << BuiltinOperInfo("pre_increment_result", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed, 0.1f, 0.5f,
2057 PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne))
2058 << BuiltinOperInfo("pre_increment_result", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed, 0.1f, 0.0f,
2059 PRECMASK_ALL, UINT_GENTYPE_FUNCS(addOne))
2060 << BuiltinOperInfo("pre_decrement_result", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 1.0f,
2061 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne))
2062 << BuiltinOperInfo("pre_decrement_result", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed, 0.1f, 0.5f,
2063 PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne))
2064 << BuiltinOperInfo("pre_decrement_result", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed, 0.1f, 0.0f,
2065 PRECMASK_ALL, UINT_GENTYPE_FUNCS(subOne))
2066 << BuiltinPostOperInfo("post_increment_result", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f,
2067 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(nop))
2068 << BuiltinPostOperInfo("post_increment_result", "++", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f,
2069 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(nop))
2070 << BuiltinPostOperInfo("post_increment_result", "++", UGT, Value(UGT, 0.0f, 9.0f), notUsed, notUsed, 0.1f, 0.0f,
2071 PRECMASK_ALL, UINT_GENTYPE_FUNCS(nop))
2072 << BuiltinPostOperInfo("post_decrement_result", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f,
2073 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(nop))
2074 << BuiltinPostOperInfo("post_decrement_result", "--", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f,
2075 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(nop))
2076 << BuiltinPostOperInfo("post_decrement_result", "--", UGT, Value(UGT, 1.0f, 10.0f), notUsed, notUsed, 0.1f,
2077 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(nop)));
2078
2079 BuiltinFuncGroup binaryOpGroup("binary_operator", "Binary operator tests");
2080
2081 // Normal binary operations and their corresponding assignment operations have lots in common; generate both in the following loop.
2082
2083 for (int binaryOperatorType = 0; binaryOperatorType <= 2;
2084 binaryOperatorType++) // 0: normal op test, 1: assignment op side-effect test, 2: assignment op result test
2085 {
2086 const bool isNormalOp = binaryOperatorType == 0;
2087 const bool isAssignEff = binaryOperatorType == 1;
2088 const bool isAssignRes = binaryOperatorType == 2;
2089
2090 DE_ASSERT(isNormalOp || isAssignEff || isAssignRes);
2091 DE_UNREF(isAssignRes);
2092
2093 const char *addName = isNormalOp ? "add" : isAssignEff ? "add_assign_effect" : "add_assign_result";
2094 const char *subName = isNormalOp ? "sub" : isAssignEff ? "sub_assign_effect" : "sub_assign_result";
2095 const char *mulName = isNormalOp ? "mul" : isAssignEff ? "mul_assign_effect" : "mul_assign_result";
2096 const char *divName = isNormalOp ? "div" : isAssignEff ? "div_assign_effect" : "div_assign_result";
2097 const char *modName = isNormalOp ? "mod" : isAssignEff ? "mod_assign_effect" : "mod_assign_result";
2098 const char *andName = isNormalOp ? "bitwise_and" :
2099 isAssignEff ? "bitwise_and_assign_effect" :
2100 "bitwise_and_assign_result";
2101 const char *orName = isNormalOp ? "bitwise_or" :
2102 isAssignEff ? "bitwise_or_assign_effect" :
2103 "bitwise_or_assign_result";
2104 const char *xorName = isNormalOp ? "bitwise_xor" :
2105 isAssignEff ? "bitwise_xor_assign_effect" :
2106 "bitwise_xor_assign_result";
2107 const char *leftShiftName = isNormalOp ? "left_shift" :
2108 isAssignEff ? "left_shift_assign_effect" :
2109 "left_shift_assign_result";
2110 const char *rightShiftName = isNormalOp ? "right_shift" :
2111 isAssignEff ? "right_shift_assign_effect" :
2112 "right_shift_assign_result";
2113 const char *addOp = isNormalOp ? "+" : "+=";
2114 const char *subOp = isNormalOp ? "-" : "-=";
2115 const char *mulOp = isNormalOp ? "*" : "*=";
2116 const char *divOp = isNormalOp ? "/" : "/=";
2117 const char *modOp = isNormalOp ? "%" : "%=";
2118 const char *andOp = isNormalOp ? "&" : "&=";
2119 const char *orOp = isNormalOp ? "|" : "|=";
2120 const char *xorOp = isNormalOp ? "^" : "^=";
2121 const char *leftShiftOp = isNormalOp ? "<<" : "<<=";
2122 const char *rightShiftOp = isNormalOp ? ">>" : ">>=";
2123
2124 // Pointer to appropriate OperInfo function.
2125 BuiltinFuncInfo (*operInfoFunc)(const char *, const char *, ValueType, Value, Value, Value, const float,
2126 const float, uint32_t, ShaderEvalFunc, ShaderEvalFunc, ShaderEvalFunc,
2127 ShaderEvalFunc) = isAssignEff ? BuiltinSideEffOperInfo : BuiltinOperInfo;
2128
2129 DE_ASSERT(operInfoFunc != DE_NULL);
2130
2131 // The following cases will be added for each operator, precision and fundamental type (float, int, uint) combination, where applicable:
2132 // gentype <op> gentype
2133 // vector <op> scalar
2134 // For normal (non-assigning) operators only:
2135 // scalar <op> vector
2136
2137 // The add operator.
2138
2139 binaryOpGroup << operInfoFunc(addName, addOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f,
2140 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(add))
2141 << operInfoFunc(addName, addOp, IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed,
2142 0.1f, 0.5f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(add))
2143 << operInfoFunc(addName, addOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2144 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(add))
2145 << operInfoFunc(addName, addOp, UGT, Value(UGT, 0.0f, 1e2f), Value(UGT, 0.0f, 1e2f), notUsed,
2146 5e-3f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(add))
2147 << operInfoFunc(addName, addOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2148 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(add))
2149 << operInfoFunc(addName, addOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2150 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addVecScalar))
2151 << operInfoFunc(addName, addOp, IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f,
2152 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(addVecScalar))
2153 << operInfoFunc(addName, addOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2154 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(addVecScalar))
2155 << operInfoFunc(addName, addOp, UV, Value(UV, 0.0f, 1e2f), Value(U, 0.0f, 1e2f), notUsed, 5e-3f,
2156 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(addVecScalar))
2157 << operInfoFunc(addName, addOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2158 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(addVecScalar));
2159
2160 if (isNormalOp)
2161 binaryOpGroup << operInfoFunc(addName, addOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
2162 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addScalarVec))
2163 << operInfoFunc(addName, addOp, IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed,
2164 0.1f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(addScalarVec))
2165 << operInfoFunc(addName, addOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2166 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(addScalarVec))
2167 << operInfoFunc(addName, addOp, UV, Value(U, 0.0f, 1e2f), Value(UV, 0.0f, 1e2f), notUsed,
2168 5e-3f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(addScalarVec))
2169 << operInfoFunc(addName, addOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2170 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(addScalarVec));
2171
2172 // The subtract operator.
2173
2174 binaryOpGroup << operInfoFunc(subName, subOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f,
2175 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(sub))
2176 << operInfoFunc(subName, subOp, IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed,
2177 0.1f, 0.5f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(sub))
2178 << operInfoFunc(subName, subOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2179 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(sub))
2180 << operInfoFunc(subName, subOp, UGT, Value(UGT, 1e2f, 2e2f), Value(UGT, 0.0f, 1e2f), notUsed,
2181 5e-3f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(sub))
2182 << operInfoFunc(subName, subOp, UGT, Value(UGT, .5e9f, 3.7e9f), Value(UGT, 0.0f, 3.9e9f), notUsed,
2183 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(sub))
2184 << operInfoFunc(subName, subOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2185 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subVecScalar))
2186 << operInfoFunc(subName, subOp, IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f,
2187 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(subVecScalar))
2188 << operInfoFunc(subName, subOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2189 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(subVecScalar))
2190 << operInfoFunc(subName, subOp, UV, Value(UV, 1e2f, 2e2f), Value(U, 0.0f, 1e2f), notUsed, 5e-3f,
2191 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(subVecScalar))
2192 << operInfoFunc(subName, subOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2193 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(subVecScalar));
2194
2195 if (isNormalOp)
2196 binaryOpGroup << operInfoFunc(subName, subOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
2197 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subScalarVec))
2198 << operInfoFunc(subName, subOp, IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed,
2199 0.1f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(subScalarVec))
2200 << operInfoFunc(subName, subOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2201 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(subScalarVec))
2202 << operInfoFunc(subName, subOp, UV, Value(U, 1e2f, 2e2f), Value(UV, 0.0f, 1e2f), notUsed,
2203 5e-3f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(subScalarVec))
2204 << operInfoFunc(subName, subOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2205 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(subScalarVec));
2206
2207 // The multiply operator.
2208
2209 binaryOpGroup << operInfoFunc(mulName, mulOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f,
2210 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(mul))
2211 << operInfoFunc(mulName, mulOp, IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed,
2212 0.1f, 0.5f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(mul))
2213 << operInfoFunc(mulName, mulOp, IGT, Value(IGT, -3e5f, 3e5f), Value(IGT, -3e4f, 3e4f), notUsed,
2214 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(mul))
2215 << operInfoFunc(mulName, mulOp, UGT, Value(UGT, 0.0f, 16.0f), Value(UGT, 0.0f, 16.0f), notUsed,
2216 4e-3f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(mul))
2217 << operInfoFunc(mulName, mulOp, UGT, Value(UGT, 0.0f, 6e5f), Value(UGT, 0.0f, 6e4f), notUsed,
2218 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(mul))
2219 << operInfoFunc(mulName, mulOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2220 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulVecScalar))
2221 << operInfoFunc(mulName, mulOp, IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f,
2222 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(mulVecScalar))
2223 << operInfoFunc(mulName, mulOp, IV, Value(IV, -3e5f, 3e5f), Value(I, -3e4f, 3e4f), notUsed,
2224 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(mulVecScalar))
2225 << operInfoFunc(mulName, mulOp, UV, Value(UV, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 4e-3f,
2226 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(mulVecScalar))
2227 << operInfoFunc(mulName, mulOp, UV, Value(UV, 0.0f, 6e5f), Value(U, 0.0f, 6e4f), notUsed, 2e-10f,
2228 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(mulVecScalar));
2229
2230 if (isNormalOp)
2231 binaryOpGroup << operInfoFunc(mulName, mulOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
2232 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulScalarVec))
2233 << operInfoFunc(mulName, mulOp, IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed,
2234 0.1f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(mulScalarVec))
2235 << operInfoFunc(mulName, mulOp, IV, Value(I, -3e5f, 3e5f), Value(IV, -3e4f, 3e4f), notUsed,
2236 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(mulScalarVec))
2237 << operInfoFunc(mulName, mulOp, UV, Value(U, 0.0f, 16.0f), Value(UV, 0.0f, 16.0f), notUsed,
2238 4e-3f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(mulScalarVec))
2239 << operInfoFunc(mulName, mulOp, UV, Value(U, 0.0f, 6e5f), Value(UV, 0.0f, 6e4f), notUsed,
2240 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(mulScalarVec));
2241
2242 // The divide operator.
2243
2244 binaryOpGroup << operInfoFunc(divName, divOp, GT, Value(GT, -1.0f, 1.0f), Value(GT, -2.0f, -0.5f), notUsed,
2245 1.0f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(div))
2246 << operInfoFunc(divName, divOp, IGT, Value(IGT, 24.0f, 24.0f), Value(IGT, -4.0f, -1.0f), notUsed,
2247 0.04f, 1.0f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(div))
2248 << operInfoFunc(divName, divOp, IGT, Value(IGT, 40320.0f, 40320.0f), Value(IGT, -8.0f, -1.0f),
2249 notUsed, 1e-5f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(div))
2250 << operInfoFunc(divName, divOp, UGT, Value(UGT, 0.0f, 24.0f), Value(UGT, 1.0f, 4.0f), notUsed,
2251 0.04f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(div))
2252 << operInfoFunc(divName, divOp, UGT, Value(UGT, 0.0f, 40320.0f), Value(UGT, 1.0f, 8.0f), notUsed,
2253 1e-5f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(div))
2254 << operInfoFunc(divName, divOp, FV, Value(FV, -1.0f, 1.0f), Value(F, -2.0f, -0.5f), notUsed, 1.0f,
2255 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divVecScalar))
2256 << operInfoFunc(divName, divOp, IV, Value(IV, 24.0f, 24.0f), Value(I, -4.0f, -1.0f), notUsed,
2257 0.04f, 1.0f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(divVecScalar))
2258 << operInfoFunc(divName, divOp, IV, Value(IV, 40320.0f, 40320.0f), Value(I, -8.0f, -1.0f),
2259 notUsed, 1e-5f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(divVecScalar))
2260 << operInfoFunc(divName, divOp, UV, Value(UV, 0.0f, 24.0f), Value(U, 1.0f, 4.0f), notUsed, 0.04f,
2261 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(divVecScalar))
2262 << operInfoFunc(divName, divOp, UV, Value(UV, 0.0f, 40320.0f), Value(U, 1.0f, 8.0f), notUsed,
2263 1e-5f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(divVecScalar));
2264
2265 if (isNormalOp)
2266 binaryOpGroup << operInfoFunc(divName, divOp, FV, Value(F, -1.0f, 1.0f), Value(FV, -2.0f, -0.5f), notUsed,
2267 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divScalarVec))
2268 << operInfoFunc(divName, divOp, IV, Value(I, 24.0f, 24.0f), Value(IV, -4.0f, -1.0f), notUsed,
2269 0.04f, 1.0f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(divScalarVec))
2270 << operInfoFunc(divName, divOp, IV, Value(I, 40320.0f, 40320.0f), Value(IV, -8.0f, -1.0f),
2271 notUsed, 1e-5f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(divScalarVec))
2272 << operInfoFunc(divName, divOp, UV, Value(U, 0.0f, 24.0f), Value(UV, 1.0f, 4.0f), notUsed,
2273 0.04f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(divScalarVec))
2274 << operInfoFunc(divName, divOp, UV, Value(U, 0.0f, 40320.0f), Value(UV, 1.0f, 8.0f), notUsed,
2275 1e-5f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(divScalarVec));
2276
2277 // The modulus operator.
2278
2279 binaryOpGroup << operInfoFunc(modName, modOp, IGT, Value(IGT, 0.0f, 6.0f), Value(IGT, 1.1f, 6.1f), notUsed,
2280 0.25f, 0.5f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(mod))
2281 << operInfoFunc(modName, modOp, IGT, Value(IGT, 0.0f, 14.0f), Value(IGT, 1.1f, 11.1f), notUsed,
2282 0.1f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(mod))
2283 << operInfoFunc(modName, modOp, UGT, Value(UGT, 0.0f, 6.0f), Value(UGT, 1.1f, 6.1f), notUsed,
2284 0.25f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(mod))
2285 << operInfoFunc(modName, modOp, UGT, Value(UGT, 0.0f, 24.0f), Value(UGT, 1.1f, 11.1f), notUsed,
2286 0.1f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(mod))
2287 << operInfoFunc(modName, modOp, IV, Value(IV, 0.0f, 6.0f), Value(I, 1.1f, 6.1f), notUsed, 0.25f,
2288 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(modVecScalar))
2289 << operInfoFunc(modName, modOp, IV, Value(IV, 0.0f, 6.0f), Value(I, 1.1f, 11.1f), notUsed, 0.1f,
2290 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(modVecScalar))
2291 << operInfoFunc(modName, modOp, UV, Value(UV, 0.0f, 6.0f), Value(U, 1.1f, 6.1f), notUsed, 0.25f,
2292 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(modVecScalar))
2293 << operInfoFunc(modName, modOp, UV, Value(UV, 0.0f, 24.0f), Value(U, 1.1f, 11.1f), notUsed, 0.1f,
2294 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(modVecScalar));
2295
2296 if (isNormalOp)
2297 binaryOpGroup << operInfoFunc(modName, modOp, IV, Value(I, 0.0f, 6.0f), Value(IV, 1.1f, 6.1f), notUsed,
2298 0.25f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(modScalarVec))
2299 << operInfoFunc(modName, modOp, IV, Value(I, 0.0f, 6.0f), Value(IV, 1.1f, 11.1f), notUsed,
2300 0.1f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(modScalarVec))
2301 << operInfoFunc(modName, modOp, UV, Value(U, 0.0f, 6.0f), Value(UV, 1.1f, 6.1f), notUsed,
2302 0.25f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(modScalarVec))
2303 << operInfoFunc(modName, modOp, UV, Value(U, 0.0f, 24.0f), Value(UV, 1.1f, 11.1f), notUsed,
2304 0.1f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(modScalarVec));
2305
2306 // The bitwise and operator.
2307
2308 binaryOpGroup << operInfoFunc(andName, andOp, IGT, Value(IGT, -16.0f, 16.0f), Value(IGT, -16.0f, 16.0f),
2309 notUsed, 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(bitwiseAnd))
2310 << operInfoFunc(andName, andOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2311 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseAnd))
2312 << operInfoFunc(andName, andOp, UGT, Value(UGT, 0.0f, 32.0f), Value(UGT, 0.0f, 32.0f), notUsed,
2313 0.03f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(bitwiseAnd))
2314 << operInfoFunc(andName, andOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2315 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseAnd))
2316 << operInfoFunc(andName, andOp, IV, Value(IV, -16.0f, 16.0f), Value(I, -16.0f, 16.0f), notUsed,
2317 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(bitwiseAndVecScalar))
2318 << operInfoFunc(andName, andOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2319 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseAndVecScalar))
2320 << operInfoFunc(andName, andOp, UV, Value(UV, 0.0f, 32.0f), Value(U, 0.0f, 32.0f), notUsed, 0.03f,
2321 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(bitwiseAndVecScalar))
2322 << operInfoFunc(andName, andOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2323 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseAndVecScalar));
2324
2325 if (isNormalOp)
2326 binaryOpGroup << operInfoFunc(andName, andOp, IV, Value(I, -16.0f, 16.0f), Value(IV, -16.0f, 16.0f),
2327 notUsed, 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(bitwiseAndScalarVec))
2328 << operInfoFunc(andName, andOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2329 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseAndScalarVec))
2330 << operInfoFunc(andName, andOp, UV, Value(U, 0.0f, 32.0f), Value(UV, 0.0f, 32.0f), notUsed,
2331 0.03f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(bitwiseAndScalarVec))
2332 << operInfoFunc(andName, andOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2333 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseAndScalarVec));
2334
2335 // The bitwise or operator.
2336
2337 binaryOpGroup << operInfoFunc(orName, orOp, IGT, Value(IGT, -16.0f, 16.0f), Value(IGT, -16.0f, 16.0f), notUsed,
2338 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(bitwiseOr))
2339 << operInfoFunc(orName, orOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2340 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseOr))
2341 << operInfoFunc(orName, orOp, UGT, Value(UGT, 0.0f, 32.0f), Value(UGT, 0.0f, 32.0f), notUsed,
2342 0.03f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(bitwiseOr))
2343 << operInfoFunc(orName, orOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2344 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseOr))
2345 << operInfoFunc(orName, orOp, IV, Value(IV, -16.0f, 16.0f), Value(I, -16.0f, 16.0f), notUsed,
2346 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(bitwiseOrVecScalar))
2347 << operInfoFunc(orName, orOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed, 4e-10f,
2348 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseOrVecScalar))
2349 << operInfoFunc(orName, orOp, UV, Value(UV, 0.0f, 32.0f), Value(U, 0.0f, 32.0f), notUsed, 0.03f,
2350 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(bitwiseOrVecScalar))
2351 << operInfoFunc(orName, orOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2352 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseOrVecScalar));
2353
2354 if (isNormalOp)
2355 binaryOpGroup << operInfoFunc(orName, orOp, IV, Value(I, -16.0f, 16.0f), Value(IV, -16.0f, 16.0f), notUsed,
2356 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(bitwiseOrScalarVec))
2357 << operInfoFunc(orName, orOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2358 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseOrScalarVec))
2359 << operInfoFunc(orName, orOp, UV, Value(U, 0.0f, 32.0f), Value(UV, 0.0f, 32.0f), notUsed,
2360 0.03f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(bitwiseOrScalarVec))
2361 << operInfoFunc(orName, orOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2362 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseOrScalarVec));
2363
2364 // The bitwise xor operator.
2365
2366 binaryOpGroup << operInfoFunc(xorName, xorOp, IGT, Value(IGT, -16.0f, 16.0f), Value(IGT, -16.0f, 16.0f),
2367 notUsed, 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_GENTYPE_FUNCS(bitwiseXor))
2368 << operInfoFunc(xorName, xorOp, IGT, Value(IGT, -2e9f, 2e9f), Value(IGT, -2e9f, 2e9f), notUsed,
2369 4e-10f, 0.5f, PRECMASK_HIGHP, INT_GENTYPE_FUNCS(bitwiseXor))
2370 << operInfoFunc(xorName, xorOp, UGT, Value(UGT, 0.0f, 32.0f), Value(UGT, 0.0f, 32.0f), notUsed,
2371 0.03f, 0.0f, PRECMASK_MEDIUMP, UINT_GENTYPE_FUNCS(bitwiseXor))
2372 << operInfoFunc(xorName, xorOp, UGT, Value(UGT, 0.0f, 4e9f), Value(UGT, 0.0f, 4e9f), notUsed,
2373 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_GENTYPE_FUNCS(bitwiseXor))
2374 << operInfoFunc(xorName, xorOp, IV, Value(IV, -16.0f, 16.0f), Value(I, -16.0f, 16.0f), notUsed,
2375 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(bitwiseXorVecScalar))
2376 << operInfoFunc(xorName, xorOp, IV, Value(IV, -2e9f, 2e9f), Value(I, -2e9f, 2e9f), notUsed,
2377 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseXorVecScalar))
2378 << operInfoFunc(xorName, xorOp, UV, Value(UV, 0.0f, 32.0f), Value(U, 0.0f, 32.0f), notUsed, 0.03f,
2379 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(bitwiseXorVecScalar))
2380 << operInfoFunc(xorName, xorOp, UV, Value(UV, 0.0f, 4e9f), Value(U, 0.0f, 4e9f), notUsed, 2e-10f,
2381 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseXorVecScalar));
2382
2383 if (isNormalOp)
2384 binaryOpGroup << operInfoFunc(xorName, xorOp, IV, Value(I, -16.0f, 16.0f), Value(IV, -16.0f, 16.0f),
2385 notUsed, 0.03f, 0.5f, PRECMASK_MEDIUMP, INT_VEC_FUNCS(bitwiseXorScalarVec))
2386 << operInfoFunc(xorName, xorOp, IV, Value(I, -2e9f, 2e9f), Value(IV, -2e9f, 2e9f), notUsed,
2387 4e-10f, 0.5f, PRECMASK_HIGHP, INT_VEC_FUNCS(bitwiseXorScalarVec))
2388 << operInfoFunc(xorName, xorOp, UV, Value(U, 0.0f, 32.0f), Value(UV, 0.0f, 32.0f), notUsed,
2389 0.03f, 0.0f, PRECMASK_MEDIUMP, UINT_VEC_FUNCS(bitwiseXorScalarVec))
2390 << operInfoFunc(xorName, xorOp, UV, Value(U, 0.0f, 4e9f), Value(UV, 0.0f, 4e9f), notUsed,
2391 2e-10f, 0.0f, PRECMASK_HIGHP, UINT_VEC_FUNCS(bitwiseXorScalarVec));
2392
2393 // The left shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
2394
2395 for (int isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++)
2396 {
2397 ValueType gType = isSignedAmount == 0 ? UGT : IGT;
2398 ValueType sType = isSignedAmount == 0 ? U : I;
2399 binaryOpGroup << operInfoFunc(leftShiftName, leftShiftOp, IGT, Value(IGT, -7.0f, 7.0f),
2400 Value(gType, 0.0f, 4.0f), notUsed, 4e-3f, 0.5f, PRECMASK_MEDIUMP,
2401 INT_GENTYPE_FUNCS(leftShift))
2402 << operInfoFunc(leftShiftName, leftShiftOp, IGT, Value(IGT, -7.0f, 7.0f),
2403 Value(gType, 0.0f, 27.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2404 INT_GENTYPE_FUNCS(leftShift))
2405 << operInfoFunc(leftShiftName, leftShiftOp, UGT, Value(UGT, 0.0f, 7.0f),
2406 Value(gType, 0.0f, 5.0f), notUsed, 4e-3f, 0.0f, PRECMASK_MEDIUMP,
2407 UINT_GENTYPE_FUNCS(leftShift))
2408 << operInfoFunc(leftShiftName, leftShiftOp, UGT, Value(UGT, 0.0f, 7.0f),
2409 Value(gType, 0.0f, 28.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2410 UINT_GENTYPE_FUNCS(leftShift))
2411 << operInfoFunc(leftShiftName, leftShiftOp, IV, Value(IV, -7.0f, 7.0f),
2412 Value(sType, 0.0f, 4.0f), notUsed, 4e-3f, 0.5f, PRECMASK_MEDIUMP,
2413 INT_VEC_FUNCS(leftShiftVecScalar))
2414 << operInfoFunc(leftShiftName, leftShiftOp, IV, Value(IV, -7.0f, 7.0f),
2415 Value(sType, 0.0f, 27.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2416 INT_VEC_FUNCS(leftShiftVecScalar))
2417 << operInfoFunc(leftShiftName, leftShiftOp, UV, Value(UV, 0.0f, 7.0f),
2418 Value(sType, 0.0f, 5.0f), notUsed, 4e-3f, 0.0f, PRECMASK_MEDIUMP,
2419 UINT_VEC_FUNCS(leftShiftVecScalar))
2420 << operInfoFunc(leftShiftName, leftShiftOp, UV, Value(UV, 0.0f, 7.0f),
2421 Value(sType, 0.0f, 28.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2422 UINT_VEC_FUNCS(leftShiftVecScalar));
2423 }
2424
2425 // The right shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
2426
2427 for (int isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++)
2428 {
2429 ValueType gType = isSignedAmount == 0 ? UGT : IGT;
2430 ValueType sType = isSignedAmount == 0 ? U : I;
2431 binaryOpGroup << operInfoFunc(rightShiftName, rightShiftOp, IGT, Value(IGT, -127.0f, 127.0f),
2432 Value(gType, 0.0f, 8.0f), notUsed, 4e-3f, 0.5f, PRECMASK_MEDIUMP,
2433 INT_GENTYPE_FUNCS(rightShift))
2434 << operInfoFunc(rightShiftName, rightShiftOp, IGT, Value(IGT, -2e9f, 2e9f),
2435 Value(gType, 0.0f, 31.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2436 INT_GENTYPE_FUNCS(rightShift))
2437 << operInfoFunc(rightShiftName, rightShiftOp, UGT, Value(UGT, 0.0f, 255.0f),
2438 Value(gType, 0.0f, 8.0f), notUsed, 4e-3f, 0.0f, PRECMASK_MEDIUMP,
2439 UINT_GENTYPE_FUNCS(rightShift))
2440 << operInfoFunc(rightShiftName, rightShiftOp, UGT, Value(UGT, 0.0f, 4e9f),
2441 Value(gType, 0.0f, 31.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2442 UINT_GENTYPE_FUNCS(rightShift))
2443 << operInfoFunc(rightShiftName, rightShiftOp, IV, Value(IV, -127.0f, 127.0f),
2444 Value(sType, 0.0f, 8.0f), notUsed, 4e-3f, 0.5f, PRECMASK_MEDIUMP,
2445 INT_VEC_FUNCS(rightShiftVecScalar))
2446 << operInfoFunc(rightShiftName, rightShiftOp, IV, Value(IV, -2e9f, 2e9f),
2447 Value(sType, 0.0f, 31.0f), notUsed, 5e-10f, 0.5f, PRECMASK_HIGHP,
2448 INT_VEC_FUNCS(rightShiftVecScalar))
2449 << operInfoFunc(rightShiftName, rightShiftOp, UV, Value(UV, 0.0f, 255.0f),
2450 Value(sType, 0.0f, 8.0f), notUsed, 4e-3f, 0.0f, PRECMASK_MEDIUMP,
2451 UINT_VEC_FUNCS(rightShiftVecScalar))
2452 << operInfoFunc(rightShiftName, rightShiftOp, UV, Value(UV, 0.0f, 4e9f),
2453 Value(sType, 0.0f, 31.0f), notUsed, 5e-10f, 0.0f, PRECMASK_HIGHP,
2454 UINT_VEC_FUNCS(rightShiftVecScalar));
2455 }
2456 }
2457
2458 // Rest of binary operators.
2459
2460 binaryOpGroup
2461 // Scalar relational operators.
2462 << BuiltinOperInfo("less", "<", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2463 PRECMASK_ALL, eval_lessThan_float, DE_NULL, DE_NULL, DE_NULL)
2464 << BuiltinOperInfo("less", "<", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
2465 PRECMASK_ALL, eval_lessThan_int, DE_NULL, DE_NULL, DE_NULL)
2466 << BuiltinOperInfo("less", "<", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f, 0.0f,
2467 PRECMASK_ALL, eval_lessThan_uint, DE_NULL, DE_NULL, DE_NULL)
2468 << BuiltinOperInfo("less_or_equal", "<=", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2469 PRECMASK_ALL, eval_lessThanEqual_float, DE_NULL, DE_NULL, DE_NULL)
2470 << BuiltinOperInfo("less_or_equal", "<=", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
2471 PRECMASK_ALL, eval_lessThanEqual_int, DE_NULL, DE_NULL, DE_NULL)
2472 << BuiltinOperInfo("less_or_equal", "<=", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f, 0.0f,
2473 PRECMASK_ALL, eval_lessThanEqual_uint, DE_NULL, DE_NULL, DE_NULL)
2474 << BuiltinOperInfo("greater", ">", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2475 PRECMASK_ALL, eval_greaterThan_float, DE_NULL, DE_NULL, DE_NULL)
2476 << BuiltinOperInfo("greater", ">", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
2477 PRECMASK_ALL, eval_greaterThan_int, DE_NULL, DE_NULL, DE_NULL)
2478 << BuiltinOperInfo("greater", ">", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f, 0.0f,
2479 PRECMASK_ALL, eval_greaterThan_uint, DE_NULL, DE_NULL, DE_NULL)
2480 << BuiltinOperInfo("greater_or_equal", ">=", B, Value(F, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f,
2481 0.0f, PRECMASK_ALL, eval_greaterThanEqual_float, DE_NULL, DE_NULL, DE_NULL)
2482 << BuiltinOperInfo("greater_or_equal", ">=", B, Value(I, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 1.0f,
2483 0.0f, PRECMASK_ALL, eval_greaterThanEqual_int, DE_NULL, DE_NULL, DE_NULL)
2484 << BuiltinOperInfo("greater_or_equal", ">=", B, Value(U, 0.0f, 16.0f), Value(U, 0.0f, 16.0f), notUsed, 1.0f,
2485 0.0f, PRECMASK_ALL, eval_greaterThanEqual_uint, DE_NULL, DE_NULL, DE_NULL)
2486
2487 // Equality comparison operators.
2488 << BuiltinOperInfo("equal", "==", B, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2489 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(allEqual))
2490 << BuiltinOperInfo("equal", "==", B, Value(IGT, -5.5f, 4.7f), Value(IGT, -2.1f, 0.1f), notUsed, 1.0f, 0.0f,
2491 PRECMASK_ALL, INT_GENTYPE_FUNCS(allEqual))
2492 << BuiltinOperInfo("equal", "==", B, Value(UGT, 0.0f, 8.0f), Value(UGT, 3.5f, 4.5f), notUsed, 1.0f, 0.0f,
2493 PRECMASK_ALL, UINT_GENTYPE_FUNCS(allEqual))
2494 << BuiltinOperInfo("equal", "==", B, Value(BGT, -2.1f, 2.1f), Value(BGT, -1.1f, 3.0f), notUsed, 1.0f, 0.0f,
2495 PRECMASK_NA, BOOL_GENTYPE_FUNCS(allEqual))
2496 << BuiltinOperInfo("not_equal", "!=", B, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2497 PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(anyNotEqual))
2498 << BuiltinOperInfo("not_equal", "!=", B, Value(IGT, -5.5f, 4.7f), Value(IGT, -2.1f, 0.1f), notUsed, 1.0f, 0.0f,
2499 PRECMASK_ALL, INT_GENTYPE_FUNCS(anyNotEqual))
2500 << BuiltinOperInfo("not_equal", "!=", B, Value(UGT, 0.0f, 8.0f), Value(UGT, 3.5f, 4.5f), notUsed, 1.0f, 0.0f,
2501 PRECMASK_ALL, UINT_GENTYPE_FUNCS(anyNotEqual))
2502 << BuiltinOperInfo("not_equal", "!=", B, Value(BGT, -2.1f, 2.1f), Value(BGT, -1.1f, 3.0f), notUsed, 1.0f, 0.0f,
2503 PRECMASK_NA, BOOL_GENTYPE_FUNCS(anyNotEqual))
2504
2505 // Logical operators.
2506 << BuiltinOperInfo("logical_and", "&&", B, Value(B, -1.0f, 1.0f), Value(B, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2507 PRECMASK_NA, BOOL_FUNCS(logicalAnd))
2508 << BuiltinOperInfo("logical_or", "||", B, Value(B, -1.0f, 1.0f), Value(B, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2509 PRECMASK_NA, BOOL_FUNCS(logicalOr))
2510 << BuiltinOperInfo("logical_xor", "^^", B, Value(B, -1.0f, 1.0f), Value(B, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2511 PRECMASK_NA, BOOL_FUNCS(logicalXor));
2512
2513 funcInfoGroups.push_back(binaryOpGroup);
2514
2515 // Common Functions.
2516 funcInfoGroups.push_back(
2517 BuiltinFuncGroup("common_functions", "Common function tests.")
2518 << BuiltinFuncInfo("min", "min", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
2519 PRECMASK_ALL, INT_GENTYPE_FUNCS(min))
2520 << BuiltinFuncInfo("min", "min", IGT, Value(IV, -4.0f, 4.0f), Value(I, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
2521 PRECMASK_ALL, INT_VEC_FUNCS(minVecScalar))
2522 << BuiltinFuncInfo("min", "min", UGT, Value(UGT, 0.0f, 8.0f), Value(UGT, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
2523 PRECMASK_ALL, UINT_GENTYPE_FUNCS(min))
2524 << BuiltinFuncInfo("min", "min", UGT, Value(UV, 0.0f, 8.0f), Value(U, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
2525 PRECMASK_ALL, UINT_VEC_FUNCS(minVecScalar))
2526 << BuiltinFuncInfo("max", "max", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
2527 PRECMASK_ALL, INT_GENTYPE_FUNCS(max))
2528 << BuiltinFuncInfo("max", "max", IGT, Value(IV, -4.0f, 4.0f), Value(I, -4.0f, 4.0f), notUsed, 0.125f, 0.5f,
2529 PRECMASK_ALL, INT_VEC_FUNCS(maxVecScalar))
2530 << BuiltinFuncInfo("max", "max", UGT, Value(UGT, 0.0f, 8.0f), Value(UGT, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
2531 PRECMASK_ALL, UINT_GENTYPE_FUNCS(max))
2532 << BuiltinFuncInfo("max", "max", UGT, Value(UV, 0.0f, 8.0f), Value(U, 0.0f, 8.0f), notUsed, 0.125f, 0.0f,
2533 PRECMASK_ALL, UINT_VEC_FUNCS(maxVecScalar))
2534 << BuiltinFuncInfo("clamp", "clamp", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -2.0f, 2.0f),
2535 Value(IGT, 2.0f, 4.0f), 0.125f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(clamp))
2536 << BuiltinFuncInfo("clamp", "clamp", IGT, Value(IV, -4.0f, 4.0f), Value(I, -2.0f, 2.0f), Value(I, 2.0f, 4.0f),
2537 0.125f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(clampVecScalarScalar))
2538 << BuiltinFuncInfo("clamp", "clamp", UGT, Value(UGT, 0.0f, 8.0f), Value(UGT, 2.0f, 6.0f),
2539 Value(UGT, 6.0f, 8.0f), 0.125f, 0.0f, PRECMASK_ALL, UINT_GENTYPE_FUNCS(clamp))
2540 << BuiltinFuncInfo("clamp", "clamp", UGT, Value(UV, 0.0f, 8.0f), Value(U, 2.0f, 6.0f), Value(U, 6.0f, 8.0f),
2541 0.125f, 0.0f, PRECMASK_ALL, UINT_VEC_FUNCS(clampVecScalarScalar)));
2542
2543 // Vector Relational Functions.
2544 funcInfoGroups.push_back(
2545 BuiltinFuncGroup("float_compare", "Floating point comparison tests.")
2546 << BuiltinFuncInfo("lessThan", "lessThan", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f,
2547 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(lessThan))
2548 << BuiltinFuncInfo("lessThanEqual", "lessThanEqual", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f),
2549 notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(lessThanEqual))
2550 << BuiltinFuncInfo("greaterThan", "greaterThan", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed,
2551 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(greaterThan))
2552 << BuiltinFuncInfo("greaterThanEqual", "greaterThanEqual", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f),
2553 notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(greaterThanEqual))
2554 << BuiltinFuncInfo("equal", "equal", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f, 0.0f,
2555 PRECMASK_ALL, FLOAT_VEC_FUNCS(equal))
2556 << BuiltinFuncInfo("notEqual", "notEqual", BV, Value(FV, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f,
2557 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(notEqual)));
2558
2559 funcInfoGroups.push_back(
2560 BuiltinFuncGroup("int_compare", "Integer comparison tests.")
2561 << BuiltinFuncInfo("lessThan", "lessThan", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed, 1.0f,
2562 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(lessThan))
2563 << BuiltinFuncInfo("lessThanEqual", "lessThanEqual", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f),
2564 notUsed, 1.0f, 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(lessThanEqual))
2565 << BuiltinFuncInfo("greaterThan", "greaterThan", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed,
2566 1.0f, 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(greaterThan))
2567 << BuiltinFuncInfo("greaterThanEqual", "greaterThanEqual", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f),
2568 notUsed, 1.0f, 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(greaterThanEqual))
2569 << BuiltinFuncInfo("equal", "equal", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed, 1.0f, 0.0f,
2570 PRECMASK_ALL, INT_VEC_FUNCS(equal))
2571 << BuiltinFuncInfo("notEqual", "notEqual", BV, Value(IV, -5.2f, 4.9f), Value(IV, -5.0f, 5.0f), notUsed, 1.0f,
2572 0.0f, PRECMASK_ALL, INT_VEC_FUNCS(notEqual)));
2573
2574 funcInfoGroups.push_back(BuiltinFuncGroup("bool_compare", "Boolean comparison tests.")
2575 << BuiltinFuncInfo("equal", "equal", BV, Value(BV, -5.2f, 4.9f), Value(BV, -5.0f, 5.0f),
2576 notUsed, 1.0f, 0.0f, PRECMASK_NA, BOOL_VEC_FUNCS(equal))
2577 << BuiltinFuncInfo("notEqual", "notEqual", BV, Value(BV, -5.2f, 4.9f),
2578 Value(BV, -5.0f, 5.0f), notUsed, 1.0f, 0.0f, PRECMASK_NA,
2579 BOOL_VEC_FUNCS(notEqual))
2580 << BuiltinFuncInfo("any", "any", B, Value(BV, -1.0f, 0.3f), notUsed, notUsed, 1.0f, 0.0f,
2581 PRECMASK_NA, BOOL_VEC_FUNCS(any))
2582 << BuiltinFuncInfo("all", "all", B, Value(BV, -0.3f, 1.0f), notUsed, notUsed, 1.0f, 0.0f,
2583 PRECMASK_NA, BOOL_VEC_FUNCS(all))
2584 << BuiltinFuncInfo("not", "not", BV, Value(BV, -1.0f, 1.0f), notUsed, notUsed, 1.0f, 0.0f,
2585 PRECMASK_NA, BOOL_VEC_FUNCS(boolNot)));
2586
2587 static const ShaderType s_shaderTypes[] = {SHADERTYPE_VERTEX, SHADERTYPE_FRAGMENT};
2588
2589 static const DataType s_floatTypes[] = {TYPE_FLOAT, TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4};
2590
2591 static const DataType s_intTypes[] = {TYPE_INT, TYPE_INT_VEC2, TYPE_INT_VEC3, TYPE_INT_VEC4};
2592
2593 static const DataType s_uintTypes[] = {TYPE_UINT, TYPE_UINT_VEC2, TYPE_UINT_VEC3, TYPE_UINT_VEC4};
2594
2595 static const DataType s_boolTypes[] = {TYPE_BOOL, TYPE_BOOL_VEC2, TYPE_BOOL_VEC3, TYPE_BOOL_VEC4};
2596
2597 for (int outerGroupNdx = 0; outerGroupNdx < (int)funcInfoGroups.size(); outerGroupNdx++)
2598 {
2599 // Create outer group.
2600 const BuiltinFuncGroup &outerGroupInfo = funcInfoGroups[outerGroupNdx];
2601 TestCaseGroup *outerGroup = new TestCaseGroup(m_testCtx, outerGroupInfo.name);
2602 addChild(outerGroup);
2603
2604 // Only create new group if name differs from previous one.
2605 TestCaseGroup *innerGroup = DE_NULL;
2606
2607 for (int funcInfoNdx = 0; funcInfoNdx < (int)outerGroupInfo.funcInfos.size(); funcInfoNdx++)
2608 {
2609 const BuiltinFuncInfo &funcInfo = outerGroupInfo.funcInfos[funcInfoNdx];
2610 const char *shaderFuncName = funcInfo.shaderFuncName;
2611 const bool isBoolCase = (funcInfo.precisionMask == PRECMASK_NA);
2612 const bool isBoolOut = (funcInfo.outValue & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0;
2613 const bool isIntOut = (funcInfo.outValue & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0;
2614 const bool isUintOut = (funcInfo.outValue & (VALUE_UINT | VALUE_UINT_VEC | VALUE_UINT_GENTYPE)) != 0;
2615 const bool isFloatOut = !isBoolOut && !isIntOut && !isUintOut;
2616
2617 if (!innerGroup || (std::string(innerGroup->getName()) != funcInfo.caseName))
2618 {
2619 std::string groupDesc = std::string("Built-in function ") + shaderFuncName + "() tests.";
2620 innerGroup = new TestCaseGroup(m_testCtx, funcInfo.caseName);
2621 outerGroup->addChild(innerGroup);
2622 }
2623
2624 for (int inScalarSize = 1; inScalarSize <= 4; inScalarSize++)
2625 {
2626 const int outScalarSize =
2627 ((funcInfo.outValue == VALUE_FLOAT) || (funcInfo.outValue == VALUE_BOOL)) ? 1 : inScalarSize;
2628 const DataType outDataType = isFloatOut ? s_floatTypes[outScalarSize - 1] :
2629 isIntOut ? s_intTypes[outScalarSize - 1] :
2630 isUintOut ? s_uintTypes[outScalarSize - 1] :
2631 isBoolOut ? s_boolTypes[outScalarSize - 1] :
2632 TYPE_LAST;
2633
2634 ShaderEvalFunc evalFunc = DE_NULL;
2635 switch (inScalarSize)
2636 {
2637 case 1:
2638 evalFunc = funcInfo.evalFuncScalar;
2639 break;
2640 case 2:
2641 evalFunc = funcInfo.evalFuncVec2;
2642 break;
2643 case 3:
2644 evalFunc = funcInfo.evalFuncVec3;
2645 break;
2646 case 4:
2647 evalFunc = funcInfo.evalFuncVec4;
2648 break;
2649 default:
2650 DE_ASSERT(false);
2651 }
2652
2653 // Skip if no valid eval func.
2654 if (evalFunc == DE_NULL)
2655 continue;
2656
2657 for (int precision = PRECISION_MEDIUMP; precision < PRECISION_LAST; precision++)
2658 {
2659 if ((funcInfo.precisionMask & (1 << precision)) ||
2660 (funcInfo.precisionMask == PRECMASK_NA &&
2661 precision == PRECISION_MEDIUMP)) // use mediump interpolators for booleans
2662 {
2663 const char *precisionStr = getPrecisionName((Precision)precision);
2664 const std::string precisionPrefix = isBoolCase ? "" : (std::string(precisionStr) + "_");
2665
2666 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
2667 {
2668 const ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
2669 const char *shaderTypeName = getShaderTypeName(shaderType);
2670 const bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX;
2671 const bool isUnaryOp = (funcInfo.input1.valueType == VALUE_NONE);
2672
2673 // \note Data type names will be added to name in a following loop.
2674 std::string name = precisionPrefix;
2675
2676 // Generate shader op.
2677 std::string shaderOp = std::string("res = ");
2678
2679 // Setup shader data info.
2680 ShaderDataSpec shaderSpec;
2681 shaderSpec.numInputs = 0;
2682 shaderSpec.precision = isBoolCase ? PRECISION_LAST : (Precision)precision;
2683 shaderSpec.output = outDataType;
2684 shaderSpec.resultScale = funcInfo.resultScale;
2685 shaderSpec.resultBias = funcInfo.resultBias;
2686 shaderSpec.referenceScale = funcInfo.referenceScale;
2687 shaderSpec.referenceBias = funcInfo.referenceBias;
2688
2689 if (funcInfo.type == OPERATOR)
2690 {
2691 if (isUnaryOp && funcInfo.isUnaryPrefix)
2692 shaderOp += shaderFuncName;
2693 }
2694 else if (funcInfo.type == FUNCTION)
2695 shaderOp += std::string(shaderFuncName) + "(";
2696 else // SIDE_EFFECT_OPERATOR
2697 shaderOp += "in0;\n\t";
2698
2699 for (int inputNdx = 0; inputNdx < MAX_INPUTS; inputNdx++)
2700 {
2701 const Value &prevV = (inputNdx == 1) ? funcInfo.input0 :
2702 (inputNdx == 2) ? funcInfo.input1 :
2703 funcInfo.input2;
2704 const Value &v = (inputNdx == 0) ? funcInfo.input0 :
2705 (inputNdx == 1) ? funcInfo.input1 :
2706 funcInfo.input2;
2707
2708 if (v.valueType == VALUE_NONE)
2709 continue; // Skip unused input.
2710
2711 const int prevInScalarSize = isScalarType(prevV.valueType) ? 1 : inScalarSize;
2712 const DataType prevInDataType =
2713 isFloatType(prevV.valueType) ? s_floatTypes[prevInScalarSize - 1] :
2714 isIntType(prevV.valueType) ? s_intTypes[prevInScalarSize - 1] :
2715 isUintType(prevV.valueType) ? s_uintTypes[prevInScalarSize - 1] :
2716 isBoolType(prevV.valueType) ? s_boolTypes[prevInScalarSize - 1] :
2717 TYPE_LAST;
2718
2719 const int curInScalarSize = isScalarType(v.valueType) ? 1 : inScalarSize;
2720 const DataType curInDataType =
2721 isFloatType(v.valueType) ? s_floatTypes[curInScalarSize - 1] :
2722 isIntType(v.valueType) ? s_intTypes[curInScalarSize - 1] :
2723 isUintType(v.valueType) ? s_uintTypes[curInScalarSize - 1] :
2724 isBoolType(v.valueType) ? s_boolTypes[curInScalarSize - 1] :
2725 TYPE_LAST;
2726
2727 // Write input type(s) to name.
2728 if (inputNdx == 0 ||
2729 prevInDataType !=
2730 curInDataType) // \note Only write input type to case name if different from previous input type (avoid overly long names).
2731 name += std::string("") + getDataTypeName(curInDataType) + "_";
2732
2733 // Generate op input source.
2734 if (funcInfo.type == OPERATOR || funcInfo.type == FUNCTION)
2735 {
2736 if (inputNdx != 0)
2737 {
2738 if (funcInfo.type == OPERATOR && !isUnaryOp)
2739 shaderOp += " " + std::string(shaderFuncName) + " ";
2740 else
2741 shaderOp += ", ";
2742 }
2743
2744 shaderOp += "in" + de::toString(inputNdx);
2745
2746 if (funcInfo.type == OPERATOR && isUnaryOp && !funcInfo.isUnaryPrefix)
2747 shaderOp += std::string(shaderFuncName);
2748 }
2749 else
2750 {
2751 DE_ASSERT(funcInfo.type == SIDE_EFFECT_OPERATOR);
2752
2753 if (inputNdx != 0 || (isUnaryOp && funcInfo.isUnaryPrefix))
2754 shaderOp += std::string("") + (isUnaryOp ? "" : " ") + shaderFuncName +
2755 (isUnaryOp ? "" : " ");
2756
2757 shaderOp +=
2758 inputNdx == 0 ?
2759 "res" :
2760 "in" +
2761 de::toString(
2762 inputNdx); // \note in0 has already been assigned to res, so start from in1.
2763
2764 if (isUnaryOp && !funcInfo.isUnaryPrefix)
2765 shaderOp += shaderFuncName;
2766 }
2767
2768 // Fill in shader info.
2769 shaderSpec.inputs[shaderSpec.numInputs++] =
2770 ShaderValue(curInDataType, v.rangeMin, v.rangeMax);
2771 }
2772
2773 if (funcInfo.type == FUNCTION)
2774 shaderOp += ")";
2775
2776 shaderOp += ";";
2777
2778 name += shaderTypeName;
2779
2780 // Create the test case.
2781 innerGroup->addChild(new ShaderOperatorCase(m_testCtx, name.c_str(), isVertexCase, evalFunc,
2782 shaderOp, shaderSpec));
2783 }
2784 }
2785 }
2786 }
2787 }
2788 }
2789
2790 // The ?: selection operator.
2791
2792 static const struct
2793 {
2794 const DataType type; // The type of "Y" and "Z" operands in "X ? Y : Z" (X is always bool).
2795 const ShaderEvalFunc evalFunc;
2796 } s_selectionInfo[] = {{TYPE_FLOAT, eval_selection_float}, {TYPE_FLOAT_VEC2, eval_selection_vec2},
2797 {TYPE_FLOAT_VEC3, eval_selection_vec3}, {TYPE_FLOAT_VEC4, eval_selection_vec4},
2798 {TYPE_INT, eval_selection_int}, {TYPE_INT_VEC2, eval_selection_ivec2},
2799 {TYPE_INT_VEC3, eval_selection_ivec3}, {TYPE_INT_VEC4, eval_selection_ivec4},
2800 {TYPE_UINT, eval_selection_uint}, {TYPE_UINT_VEC2, eval_selection_uvec2},
2801 {TYPE_UINT_VEC3, eval_selection_uvec3}, {TYPE_UINT_VEC4, eval_selection_uvec4},
2802 {TYPE_BOOL, eval_selection_bool}, {TYPE_BOOL_VEC2, eval_selection_bvec2},
2803 {TYPE_BOOL_VEC3, eval_selection_bvec3}, {TYPE_BOOL_VEC4, eval_selection_bvec4}};
2804
2805 TestCaseGroup *selectionGroup = new TestCaseGroup(m_testCtx, "selection");
2806 addChild(selectionGroup);
2807
2808 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_selectionInfo); typeNdx++)
2809 {
2810 const DataType curType = s_selectionInfo[typeNdx].type;
2811 const ShaderEvalFunc evalFunc = s_selectionInfo[typeNdx].evalFunc;
2812 const bool isBoolCase = isDataTypeBoolOrBVec(curType);
2813 const bool isFloatCase = isDataTypeFloatOrVec(curType);
2814 const bool isIntCase = isDataTypeIntOrIVec(curType);
2815 const bool isUintCase = isDataTypeUintOrUVec(curType);
2816 const char *dataTypeStr = getDataTypeName(curType);
2817
2818 DE_ASSERT(isBoolCase || isFloatCase || isIntCase || isUintCase);
2819 DE_UNREF(isIntCase);
2820
2821 for (int precision = (int)PRECISION_MEDIUMP; precision < (int)PRECISION_LAST; precision++)
2822 {
2823 if (isBoolCase && precision != PRECISION_MEDIUMP) // Use mediump interpolators for booleans.
2824 continue;
2825
2826 const char *precisionStr = getPrecisionName((Precision)precision);
2827 std::string precisionPrefix = isBoolCase ? "" : (std::string(precisionStr) + "_");
2828
2829 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
2830 {
2831 const ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
2832 const char *shaderTypeName = getShaderTypeName(shaderType);
2833 const bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX;
2834
2835 std::string name = precisionPrefix + dataTypeStr + "_" + shaderTypeName;
2836
2837 ShaderDataSpec shaderSpec;
2838 shaderSpec.numInputs = 3;
2839 shaderSpec.precision = isBoolCase ? PRECISION_LAST : (Precision)precision;
2840 shaderSpec.output = curType;
2841 shaderSpec.resultScale = (isBoolCase ? 1.0f : (isFloatCase ? 0.5f : (isUintCase ? 0.5f : 0.1f)));
2842 shaderSpec.resultBias = (isBoolCase ? 0.0f : (isFloatCase ? 0.5f : (isUintCase ? 0.0f : 0.5f)));
2843 shaderSpec.referenceScale = shaderSpec.resultScale;
2844 shaderSpec.referenceBias = shaderSpec.resultBias;
2845
2846 const float rangeMin = (isBoolCase ? -1.0f : (isFloatCase ? -1.0f : (isUintCase ? 0.0f : -5.0f)));
2847 const float rangeMax = (isBoolCase ? 1.0f : (isFloatCase ? 1.0f : (isUintCase ? 2.0f : 5.0f)));
2848
2849 shaderSpec.inputs[0] = ShaderValue(TYPE_BOOL, -1.0f, 1.0f);
2850 shaderSpec.inputs[1] = ShaderValue(curType, rangeMin, rangeMax);
2851 shaderSpec.inputs[2] = ShaderValue(curType, rangeMin, rangeMax);
2852
2853 selectionGroup->addChild(new ShaderOperatorCase(m_testCtx, name.c_str(), isVertexCase, evalFunc,
2854 "res = in0 ? in1 : in2;", shaderSpec));
2855 }
2856 }
2857 }
2858
2859 // The sequence operator (comma).
2860
2861 TestCaseGroup *sequenceGroup = new TestCaseGroup(m_testCtx, "sequence");
2862 addChild(sequenceGroup);
2863
2864 TestCaseGroup *sequenceNoSideEffGroup = new TestCaseGroup(m_testCtx, "no_side_effects");
2865 TestCaseGroup *sequenceSideEffGroup = new TestCaseGroup(m_testCtx, "side_effects");
2866 sequenceGroup->addChild(sequenceNoSideEffGroup);
2867 sequenceGroup->addChild(sequenceSideEffGroup);
2868
2869 static const struct
2870 {
2871 const bool containsSideEffects;
2872 const char *caseName;
2873 const char *expressionStr;
2874 const int numInputs;
2875 const DataType inputTypes[MAX_INPUTS];
2876 const DataType resultType;
2877 const ShaderEvalFunc evalFunc;
2878 } s_sequenceCases[] = {{false,
2879 "vec4",
2880 "in0, in2 + in1, in1 + in0",
2881 3,
2882 {TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4},
2883 TYPE_FLOAT_VEC4,
2884 evalSequenceNoSideEffCase0},
2885 {false,
2886 "float_uint",
2887 "in0 + in2, in1 + in1",
2888 3,
2889 {TYPE_FLOAT, TYPE_UINT, TYPE_FLOAT},
2890 TYPE_UINT,
2891 evalSequenceNoSideEffCase1},
2892 {false,
2893 "bool_vec2",
2894 "in0 && in1, in0, ivec2(vec2(in0) + in2)",
2895 3,
2896 {TYPE_BOOL, TYPE_BOOL, TYPE_FLOAT_VEC2},
2897 TYPE_INT_VEC2,
2898 evalSequenceNoSideEffCase2},
2899 {false,
2900 "vec4_ivec4_bvec4",
2901 "in0 + vec4(in1), in2, in1",
2902 3,
2903 {TYPE_FLOAT_VEC4, TYPE_INT_VEC4, TYPE_BOOL_VEC4},
2904 TYPE_INT_VEC4,
2905 evalSequenceNoSideEffCase3},
2906
2907 {true,
2908 "vec4",
2909 "in0++, in1 = in0 + in2, in2 = in1",
2910 3,
2911 {TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4},
2912 TYPE_FLOAT_VEC4,
2913 evalSequenceSideEffCase0},
2914 {true,
2915 "float_uint",
2916 "in1++, in0 = float(in1), in1 = uint(in0 + in2)",
2917 3,
2918 {TYPE_FLOAT, TYPE_UINT, TYPE_FLOAT},
2919 TYPE_UINT,
2920 evalSequenceSideEffCase1},
2921 {true,
2922 "bool_vec2",
2923 "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)",
2924 3,
2925 {TYPE_BOOL, TYPE_BOOL, TYPE_FLOAT_VEC2},
2926 TYPE_INT_VEC2,
2927 evalSequenceSideEffCase2},
2928 {true,
2929 "vec4_ivec4_bvec4",
2930 "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++",
2931 3,
2932 {TYPE_FLOAT_VEC4, TYPE_INT_VEC4, TYPE_BOOL_VEC4},
2933 TYPE_INT_VEC4,
2934 evalSequenceSideEffCase3}};
2935
2936 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_sequenceCases); caseNdx++)
2937 {
2938 for (int precision = (int)PRECISION_MEDIUMP; precision < (int)PRECISION_LAST; precision++)
2939 {
2940 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
2941 {
2942 const ShaderType shaderType = s_shaderTypes[shaderTypeNdx];
2943 const char *shaderTypeName = getShaderTypeName(shaderType);
2944 const bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX;
2945
2946 std::string name = std::string("") + getPrecisionName((Precision)precision) + "_" +
2947 s_sequenceCases[caseNdx].caseName + "_" + shaderTypeName;
2948
2949 ShaderDataSpec shaderSpec;
2950 shaderSpec.numInputs = s_sequenceCases[caseNdx].numInputs;
2951 shaderSpec.precision = (Precision)precision;
2952 shaderSpec.output = s_sequenceCases[caseNdx].resultType;
2953 shaderSpec.resultScale = 0.5f;
2954 shaderSpec.resultBias = 0.0f;
2955 shaderSpec.referenceScale = shaderSpec.resultScale;
2956 shaderSpec.referenceBias = shaderSpec.resultBias;
2957
2958 for (int inputNdx = 0; inputNdx < s_sequenceCases[caseNdx].numInputs; inputNdx++)
2959 {
2960 const DataType type = s_sequenceCases[caseNdx].inputTypes[inputNdx];
2961 const float rangeMin =
2962 (isDataTypeFloatOrVec(type) ?
2963 -0.5f :
2964 (isDataTypeIntOrIVec(type) ? -2.0f : (isDataTypeUintOrUVec(type) ? 0.0f : -1.0f)));
2965 const float rangeMax =
2966 (isDataTypeFloatOrVec(type) ?
2967 0.5f :
2968 (isDataTypeIntOrIVec(type) ? 2.0f : (isDataTypeUintOrUVec(type) ? 2.0f : 1.0f)));
2969
2970 shaderSpec.inputs[inputNdx] = ShaderValue(type, rangeMin, rangeMax);
2971 }
2972
2973 const std::string expression =
2974 std::string("") + "res = (" + s_sequenceCases[caseNdx].expressionStr + ");";
2975
2976 TestCaseGroup *group =
2977 s_sequenceCases[caseNdx].containsSideEffects ? sequenceSideEffGroup : sequenceNoSideEffGroup;
2978 group->addChild(new ShaderOperatorCase(m_testCtx, name.c_str(), isVertexCase,
2979 s_sequenceCases[caseNdx].evalFunc, expression.c_str(),
2980 shaderSpec));
2981 }
2982 }
2983 }
2984 }
2985
2986 } // namespace
2987
createOperatorTests(tcu::TestContext & testCtx)2988 tcu::TestCaseGroup *createOperatorTests(tcu::TestContext &testCtx)
2989 {
2990 return new ShaderOperatorTests(testCtx);
2991 }
2992
2993 } // namespace sr
2994 } // namespace vkt
2995