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