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