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