1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 2.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 "es2fShaderOperatorTests.hpp" 25 #include "glsShaderRenderCase.hpp" 26 #include "gluShaderUtil.hpp" 27 #include "tcuVectorUtil.hpp" 28 29 #include "deStringUtil.hpp" 30 #include "deInt32.h" 31 #include "deMemory.h" 32 33 #include <map> 34 35 using namespace tcu; 36 using namespace glu; 37 using namespace deqp::gls; 38 39 using std::map; 40 using std::pair; 41 using std::vector; 42 using std::string; 43 using std::ostringstream; 44 45 namespace deqp 46 { 47 namespace gles2 48 { 49 namespace Functional 50 { 51 52 #if defined(abs) 53 # undef abs 54 #endif 55 56 using de::min; 57 using de::max; 58 using de::clamp; 59 60 // \note VS2013 gets confused without these 61 using tcu::exp2; 62 using tcu::log2; 63 64 inline float abs (float v) { return deFloatAbs(v); } 65 66 inline bool logicalAnd (bool a, bool b) { return (a && b); } 67 inline bool logicalOr (bool a, bool b) { return (a || b); } 68 inline bool logicalXor (bool a, bool b) { return (a != b); } 69 70 #define DEFINE_VEC_FLOAT_FUNCTION(FUNC_NAME, SCALAR_OP_NAME) \ 71 template<int Size> \ 72 inline Vector<float, Size> FUNC_NAME (const Vector<float, Size>& v, float s) \ 73 { \ 74 Vector<float, Size> res; \ 75 for (int i = 0; i < Size; i++) \ 76 res[i] = SCALAR_OP_NAME(v[i], s); \ 77 return res; \ 78 } 79 80 #define DEFINE_FLOAT_VEC_FUNCTION(FUNC_NAME, SCALAR_OP_NAME) \ 81 template<int Size> \ 82 inline Vector<float, Size> FUNC_NAME (float s, const Vector<float, Size>& v) \ 83 { \ 84 Vector<float, Size> res; \ 85 for (int i = 0; i < Size; i++) \ 86 res[i] = SCALAR_OP_NAME(s, v[i]); \ 87 return res; \ 88 } 89 90 #define DEFINE_VEC_VEC_FLOAT_FUNCTION(FUNC_NAME, SCALAR_OP_NAME) \ 91 template<int Size> \ 92 inline Vector<float, Size> FUNC_NAME (const Vector<float, Size>& v0, const Vector<float, Size>& v1, float s) \ 93 { \ 94 Vector<float, Size> res; \ 95 for (int i = 0; i < Size; i++) \ 96 res[i] = SCALAR_OP_NAME(v0[i], v1[i], s); \ 97 return res; \ 98 } 99 100 #define DEFINE_VEC_FLOAT_FLOAT_FUNCTION(FUNC_NAME, SCALAR_OP_NAME) \ 101 template<int Size> \ 102 inline Vector<float, Size> FUNC_NAME (const Vector<float, Size>& v, float s0, float s1) \ 103 { \ 104 Vector<float, Size> res; \ 105 for (int i = 0; i < Size; i++) \ 106 res[i] = SCALAR_OP_NAME(v[i], s0, s1); \ 107 return res; \ 108 } 109 110 #define DEFINE_FLOAT_FLOAT_VEC_FUNCTION(FUNC_NAME, SCALAR_OP_NAME) \ 111 template<int Size> \ 112 inline Vector<float, Size> FUNC_NAME (float s0, float s1, const Vector<float, Size>& v) \ 113 { \ 114 Vector<float, Size> res; \ 115 for (int i = 0; i < Size; i++) \ 116 res[i] = SCALAR_OP_NAME(s0, s1, v[i]); \ 117 return res; \ 118 } 119 120 DEFINE_VEC_FLOAT_FUNCTION (modVecFloat, mod) 121 DEFINE_VEC_FLOAT_FUNCTION (minVecFloat, min) 122 DEFINE_VEC_FLOAT_FUNCTION (maxVecFloat, max) 123 DEFINE_VEC_FLOAT_FLOAT_FUNCTION (clampVecFloatFloat, clamp) 124 DEFINE_VEC_VEC_FLOAT_FUNCTION (mixVecVecFloat, mix) 125 DEFINE_FLOAT_VEC_FUNCTION (stepFloatVec, step) 126 DEFINE_FLOAT_FLOAT_VEC_FUNCTION (smoothStepFloatFloatVec, smoothStep) 127 128 #undef DEFINE_VEC_FLOAT_FUNCTION 129 #undef DEFINE_VEC_VEC_FLOAT_FUNCTION 130 #undef DEFINE_VEC_FLOAT_FLOAT_FUNCTION 131 #undef DEFINE_FLOAT_FLOAT_VEC_FUNCTION 132 133 inline float addOne (float v) { return v + 1.0f; }; 134 inline float subOne (float v) { return v - 1.0f; }; 135 inline int addOne (int v) { return v + 1; }; 136 inline int subOne (int v) { return v - 1; }; 137 138 template<int Size> inline Vector<float, Size> addOne (const Vector<float, Size>& v) { return v + 1.0f; }; 139 template<int Size> inline Vector<float, Size> subOne (const Vector<float, Size>& v) { return v - 1.0f; }; 140 template<int Size> inline Vector<int, Size> addOne (const Vector<int, Size>& v) { return v + 1; }; 141 template<int Size> inline Vector<int, Size> subOne (const Vector<int, Size>& v) { return v - 1; }; 142 143 template<typename T> inline T selection (bool cond, T a, T b) { return cond ? a : b; }; 144 145 template<typename T, int Size> inline Vector<T, Size> addVecScalar (const Vector<T, Size>& v, T s) { return v + s; }; 146 template<typename T, int Size> inline Vector<T, Size> subVecScalar (const Vector<T, Size>& v, T s) { return v - s; }; 147 template<typename T, int Size> inline Vector<T, Size> mulVecScalar (const Vector<T, Size>& v, T s) { return v * s; }; 148 template<typename T, int Size> inline Vector<T, Size> divVecScalar (const Vector<T, Size>& v, T s) { return v / s; }; 149 150 template<typename T, int Size> inline Vector<T, Size> addScalarVec (T s, const Vector<T, Size>& v) { return s + v; }; 151 template<typename T, int Size> inline Vector<T, Size> subScalarVec (T s, const Vector<T, Size>& v) { return s - v; }; 152 template<typename T, int Size> inline Vector<T, Size> mulScalarVec (T s, const Vector<T, Size>& v) { return s * v; }; 153 template<typename T, int Size> inline Vector<T, Size> divScalarVec (T s, const Vector<T, Size>& v) { return s / v; }; 154 155 // Reference functions for specific sequence operations for the sequence operator tests. 156 157 // Reference for expression "in0, in2 + in1, in1 + in0" 158 inline Vec4 sequenceNoSideEffCase0 (const Vec4& in0, const Vec4& in1, const Vec4& in2) { DE_UNREF(in2); return in1 + in0; } 159 // Reference for expression "in0, in2 + in1, in1 + in0" 160 inline int sequenceNoSideEffCase1 (float in0, int in1, float in2) { DE_UNREF(in0); DE_UNREF(in2); return in1 + in1; } 161 // Reference for expression "in0 && in1, in0, ivec2(vec2(in0) + in2)" 162 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())); } 163 // Reference for expression "in0 + vec4(in1), in2, in1" 164 inline IVec4 sequenceNoSideEffCase3 (const Vec4& in0, const IVec4& in1, const BVec4& in2) { DE_UNREF(in0); DE_UNREF(in2); return in1; } 165 // Reference for expression "in0++, in1 = in0 + in2, in2 = in1" 166 inline Vec4 sequenceSideEffCase0 (const Vec4& in0, const Vec4& in1, const Vec4& in2) { DE_UNREF(in1); return in0 + 1.0f + in2; } 167 // Reference for expression "in1++, in0 = float(in1), in1 = int(in0 + in2)" 168 inline int sequenceSideEffCase1 (float in0, int in1, float in2) { DE_UNREF(in0); return (int)(float(in1) + 1.0f + in2); } 169 // Reference for expression "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)" 170 inline IVec2 sequenceSideEffCase2 (bool in0, bool in1, const Vec2& in2) { DE_UNREF(in1); return (in2 + Vec2(1.0f) + Vec2((float)in0)).asInt(); } 171 // Reference for expression "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++" 172 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(); } 173 174 // ShaderEvalFunc-type wrappers for the above functions. 175 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)); } 176 void evalSequenceNoSideEffCase1 (ShaderEvalContext& ctx) { ctx.color.x() = (float)sequenceNoSideEffCase1(ctx.in[0].z(), (int)ctx.in[1].x(), ctx.in[2].y()); } 177 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(); } 178 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(); } 179 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)); } 180 void evalSequenceSideEffCase1 (ShaderEvalContext& ctx) { ctx.color.x() = (float)sequenceSideEffCase1(ctx.in[0].z(), (int)ctx.in[1].x(), ctx.in[2].y()); } 181 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(); } 182 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(); } 183 184 enum 185 { 186 MAX_INPUTS = 3 187 }; 188 189 enum PrecisionMask 190 { 191 PRECMASK_NA = 0, //!< Precision not applicable (booleans) 192 PRECMASK_LOWP = (1<<PRECISION_LOWP), 193 PRECMASK_MEDIUMP = (1<<PRECISION_MEDIUMP), 194 PRECMASK_HIGHP = (1<<PRECISION_HIGHP), 195 196 PRECMASK_MEDIUMP_HIGHP = (1<<PRECISION_MEDIUMP) | (1<<PRECISION_HIGHP), 197 PRECMASK_ALL = (1<<PRECISION_LOWP) | (1<<PRECISION_MEDIUMP) | (1<<PRECISION_HIGHP) 198 }; 199 200 enum ValueType 201 { 202 VALUE_NONE = 0, 203 VALUE_FLOAT = (1<<0), // float scalar 204 VALUE_FLOAT_VEC = (1<<1), // float vector 205 VALUE_FLOAT_GENTYPE = (1<<2), // float scalar/vector 206 VALUE_VEC3 = (1<<3), // vec3 only 207 VALUE_MATRIX = (1<<4), // matrix 208 VALUE_BOOL = (1<<5), // boolean scalar 209 VALUE_BOOL_VEC = (1<<6), // boolean vector 210 VALUE_BOOL_GENTYPE = (1<<7), // boolean scalar/vector 211 VALUE_INT = (1<<8), // int scalar 212 VALUE_INT_VEC = (1<<9), // int vector 213 VALUE_INT_GENTYPE = (1<<10), // int scalar/vector 214 215 // Shorthands. 216 F = VALUE_FLOAT, 217 FV = VALUE_FLOAT_VEC, 218 GT = VALUE_FLOAT_GENTYPE, 219 V3 = VALUE_VEC3, 220 M = VALUE_MATRIX, 221 B = VALUE_BOOL, 222 BV = VALUE_BOOL_VEC, 223 BGT = VALUE_BOOL_GENTYPE, 224 I = VALUE_INT, 225 IV = VALUE_INT_VEC, 226 IGT = VALUE_INT_GENTYPE 227 }; 228 229 static inline bool isScalarType (ValueType type) 230 { 231 return type == VALUE_FLOAT || type == VALUE_BOOL || type == VALUE_INT; 232 } 233 234 struct Value 235 { 236 Value (ValueType valueType_, float rangeMin_, float rangeMax_) 237 : valueType (valueType_) 238 , rangeMin (rangeMin_) 239 , rangeMax (rangeMax_) 240 { 241 } 242 243 ValueType valueType; 244 float rangeMin; 245 float rangeMax; 246 }; 247 248 enum OperationType 249 { 250 FUNCTION = 0, 251 OPERATOR, 252 SIDE_EFFECT_OPERATOR // Test the side-effect (as opposed to the result) of a side-effect operator. 253 }; 254 255 struct BuiltinFuncInfo 256 { 257 BuiltinFuncInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, float resultScale_, float resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_, OperationType type_=FUNCTION, bool isUnaryPrefix_=true) 258 : caseName (caseName_) 259 , shaderFuncName (shaderFuncName_) 260 , outValue (outValue_) 261 , input0 (input0_) 262 , input1 (input1_) 263 , input2 (input2_) 264 , resultScale (resultScale_) 265 , resultBias (resultBias_) 266 , precisionMask (precisionMask_) 267 , evalFuncScalar (evalFuncScalar_) 268 , evalFuncVec2 (evalFuncVec2_) 269 , evalFuncVec3 (evalFuncVec3_) 270 , evalFuncVec4 (evalFuncVec4_) 271 , type (type_) 272 , isUnaryPrefix (isUnaryPrefix_) 273 { 274 } 275 276 const char* caseName; //!< Name of case. 277 const char* shaderFuncName; //!< Name in shading language. 278 ValueType outValue; 279 Value input0; 280 Value input1; 281 Value input2; 282 float resultScale; 283 float resultBias; 284 deUint32 precisionMask; 285 ShaderEvalFunc evalFuncScalar; 286 ShaderEvalFunc evalFuncVec2; 287 ShaderEvalFunc evalFuncVec3; 288 ShaderEvalFunc evalFuncVec4; 289 OperationType type; 290 bool isUnaryPrefix; //!< Whether a unary operator is a prefix operator; redundant unless unary. 291 }; 292 293 static inline BuiltinFuncInfo BuiltinOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, float resultScale_, float resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_) 294 { 295 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, OPERATOR); 296 } 297 298 // For postfix (unary) operators. 299 static inline BuiltinFuncInfo BuiltinPostOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, float resultScale_, float resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_) 300 { 301 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, OPERATOR, false); 302 } 303 304 static inline BuiltinFuncInfo BuiltinSideEffOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, float resultScale_, float resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_) 305 { 306 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, SIDE_EFFECT_OPERATOR); 307 } 308 309 // For postfix (unary) operators, testing side-effect. 310 static inline BuiltinFuncInfo BuiltinPostSideEffOperInfo (const char* caseName_, const char* shaderFuncName_, ValueType outValue_, Value input0_, Value input1_, Value input2_, float resultScale_, float resultBias_, deUint32 precisionMask_, ShaderEvalFunc evalFuncScalar_, ShaderEvalFunc evalFuncVec2_, ShaderEvalFunc evalFuncVec3_, ShaderEvalFunc evalFuncVec4_) 311 { 312 return BuiltinFuncInfo(caseName_, shaderFuncName_, outValue_, input0_, input1_, input2_, resultScale_, resultBias_, precisionMask_, evalFuncScalar_, evalFuncVec2_, evalFuncVec3_, evalFuncVec4_, SIDE_EFFECT_OPERATOR, false); 313 } 314 315 // BuiltinFuncGroup 316 317 struct BuiltinFuncGroup 318 { 319 BuiltinFuncGroup (const char* name_, const char* description_) : name(name_), description(description_) {} 320 BuiltinFuncGroup& operator<< (const BuiltinFuncInfo& info) { funcInfos.push_back(info); return *this; } 321 322 const char* name; 323 const char* description; 324 std::vector<BuiltinFuncInfo> funcInfos; 325 }; 326 327 static const char* s_inSwizzles[MAX_INPUTS][4] = 328 { 329 { "z", "wy", "zxy", "yzwx" }, 330 { "x", "yx", "yzx", "wzyx" }, 331 { "y", "zy", "wyz", "xwzy" } 332 }; 333 334 static const char* s_outSwizzles[] = { "x", "yz", "xyz", "xyzw" }; 335 336 // OperatorShaderEvaluator 337 338 class OperatorShaderEvaluator : public ShaderEvaluator 339 { 340 public: 341 OperatorShaderEvaluator (ShaderEvalFunc evalFunc, float scale, float bias) 342 { 343 m_evalFunc = evalFunc; 344 m_scale = scale; 345 m_bias = bias; 346 } 347 348 virtual ~OperatorShaderEvaluator (void) 349 { 350 } 351 352 virtual void evaluate (ShaderEvalContext& ctx) 353 { 354 m_evalFunc(ctx); 355 ctx.color = ctx.color * m_scale + m_bias; 356 } 357 358 private: 359 ShaderEvalFunc m_evalFunc; 360 float m_scale; 361 float m_bias; 362 }; 363 364 // Concrete value. 365 366 struct ShaderValue 367 { 368 ShaderValue (DataType type_, float rangeMin_, float rangeMax_) 369 : type (type_) 370 , rangeMin (rangeMin_) 371 , rangeMax (rangeMax_) 372 { 373 } 374 375 ShaderValue (void) 376 : type (TYPE_LAST) 377 , rangeMin (0.0f) 378 , rangeMax (0.0f) 379 { 380 } 381 382 DataType type; 383 float rangeMin; 384 float rangeMax; 385 }; 386 387 struct ShaderDataSpec 388 { 389 ShaderDataSpec (void) 390 : resultScale (1.0f) 391 , resultBias (0.0f) 392 , precision (PRECISION_LAST) 393 , output (TYPE_LAST) 394 , numInputs (0) 395 { 396 } 397 398 float resultScale; 399 float resultBias; 400 Precision precision; 401 DataType output; 402 int numInputs; 403 ShaderValue inputs[MAX_INPUTS]; 404 }; 405 406 // ShaderOperatorCase 407 408 class ShaderOperatorCase : public ShaderRenderCase 409 { 410 public: 411 ShaderOperatorCase (Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* shaderOp, const ShaderDataSpec& spec); 412 virtual ~ShaderOperatorCase (void); 413 414 private: 415 ShaderOperatorCase (const ShaderOperatorCase&); // not allowed! 416 ShaderOperatorCase& operator= (const ShaderOperatorCase&); // not allowed! 417 418 OperatorShaderEvaluator m_evaluator; 419 }; 420 421 ShaderOperatorCase::ShaderOperatorCase (Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* shaderOp, const ShaderDataSpec& spec) 422 : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), caseName, description, isVertexCase, m_evaluator) 423 , m_evaluator(evalFunc, spec.resultScale, spec.resultBias) 424 { 425 const char* precision = spec.precision != PRECISION_LAST ? getPrecisionName(spec.precision) : DE_NULL; 426 const char* inputPrecision[MAX_INPUTS]; 427 428 ostringstream vtx; 429 ostringstream frag; 430 ostringstream& op = isVertexCase ? vtx : frag; 431 432 // Compute precision for inputs. 433 for (int i = 0; i < spec.numInputs; i++) 434 { 435 bool isBoolVal = de::inRange<int>(spec.inputs[i].type, TYPE_BOOL, TYPE_BOOL_VEC4); 436 bool isIntVal = de::inRange<int>(spec.inputs[i].type, TYPE_INT, TYPE_INT_VEC4); 437 // \note Mediump interpolators are used for booleans and lowp ints. 438 Precision prec = isBoolVal || (isIntVal && spec.precision == PRECISION_LOWP) ? PRECISION_MEDIUMP : spec.precision; 439 inputPrecision[i] = getPrecisionName(prec); 440 } 441 442 // Attributes. 443 vtx << "attribute highp vec4 a_position;\n"; 444 for (int i = 0; i < spec.numInputs; i++) 445 vtx << "attribute " << inputPrecision[i] << " vec4 a_in" << i << ";\n"; 446 447 if (isVertexCase) 448 { 449 vtx << "varying mediump vec4 v_color;\n"; 450 frag << "varying mediump vec4 v_color;\n"; 451 } 452 else 453 { 454 for (int i = 0; i < spec.numInputs; i++) 455 { 456 vtx << "varying " << inputPrecision[i] << " vec4 v_in" << i << ";\n"; 457 frag << "varying " << inputPrecision[i] << " vec4 v_in" << i << ";\n"; 458 } 459 } 460 461 vtx << "\n"; 462 vtx << "void main()\n"; 463 vtx << "{\n"; 464 vtx << " gl_Position = a_position;\n"; 465 466 frag << "\n"; 467 frag << "void main()\n"; 468 frag << "{\n"; 469 470 // Expression inputs. 471 string prefix = isVertexCase ? "a_" : "v_"; 472 for (int i = 0; i < spec.numInputs; i++) 473 { 474 DataType inType = spec.inputs[i].type; 475 int inSize = getDataTypeScalarSize(inType); 476 bool isInt = de::inRange<int>(inType, TYPE_INT, TYPE_INT_VEC4); 477 bool isBool = de::inRange<int>(inType, TYPE_BOOL, TYPE_BOOL_VEC4); 478 const char* typeName = getDataTypeName(inType); 479 const char* swizzle = s_inSwizzles[i][inSize-1]; 480 481 op << "\t"; 482 if (precision && !isBool) op << precision << " "; 483 484 op << typeName << " in" << i << " = "; 485 486 if (isBool) 487 { 488 if (inSize == 1) op << "("; 489 else op << "greaterThan("; 490 } 491 else if (isInt) 492 op << typeName << "("; 493 494 op << prefix << "in" << i << "." << swizzle; 495 496 if (isBool) 497 { 498 if (inSize == 1) op << " > 0.0)"; 499 else op << ", vec" << inSize << "(0.0))"; 500 } 501 else if (isInt) 502 op << ")"; 503 504 op << ";\n"; 505 } 506 507 // Result variable. 508 { 509 const char* outTypeName = getDataTypeName(spec.output); 510 bool isBoolOut = de::inRange<int>(spec.output, TYPE_BOOL, TYPE_BOOL_VEC4); 511 512 op << "\t"; 513 if (precision && !isBoolOut) op << precision << " "; 514 op << outTypeName << " res = " << outTypeName << "(0.0);\n\n"; 515 } 516 517 // Expression. 518 op << "\t" << shaderOp << "\n\n"; 519 520 // Convert to color. 521 bool isResFloatVec = de::inRange<int>(spec.output, TYPE_FLOAT, TYPE_FLOAT_VEC4); 522 int outScalarSize = getDataTypeScalarSize(spec.output); 523 524 op << "\tmediump vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n"; 525 op << "\tcolor." << s_outSwizzles[outScalarSize-1] << " = "; 526 527 if (!isResFloatVec && outScalarSize == 1) 528 op << "float(res)"; 529 else if (!isResFloatVec) 530 op << "vec" << outScalarSize << "(res)"; 531 else 532 op << "res"; 533 534 op << ";\n"; 535 536 // Scale & bias. 537 float resultScale = spec.resultScale; 538 float resultBias = spec.resultBias; 539 if ((resultScale != 1.0f) || (resultBias != 0.0f)) 540 { 541 op << "\tcolor = color"; 542 if (resultScale != 1.0f) op << " * " << de::floatToString(resultScale, 2); 543 if (resultBias != 0.0f) op << " + " << de::floatToString(resultBias, 2); 544 op << ";\n"; 545 } 546 547 // .. 548 if (isVertexCase) 549 { 550 vtx << " v_color = color;\n"; 551 frag << " gl_FragColor = v_color;\n"; 552 } 553 else 554 { 555 for (int i = 0; i < spec.numInputs; i++) 556 vtx << " v_in" << i << " = a_in" << i << ";\n"; 557 frag << " gl_FragColor = color;\n"; 558 } 559 560 vtx << "}\n"; 561 frag << "}\n"; 562 563 m_vertShaderSource = vtx.str(); 564 m_fragShaderSource = frag.str(); 565 566 // Setup the user attributes. 567 m_userAttribTransforms.resize(spec.numInputs); 568 for (int inputNdx = 0; inputNdx < spec.numInputs; inputNdx++) 569 { 570 const ShaderValue& v = spec.inputs[inputNdx]; 571 DE_ASSERT(v.type != TYPE_LAST); 572 573 float scale = (v.rangeMax - v.rangeMin); 574 float minBias = v.rangeMin; 575 float maxBias = v.rangeMax; 576 Mat4 attribMatrix; 577 578 for (int rowNdx = 0; rowNdx < 4; rowNdx++) 579 { 580 Vec4 row; 581 582 switch ((rowNdx + inputNdx) % 4) 583 { 584 case 0: row = Vec4(scale, 0.0f, 0.0f, minBias); break; 585 case 1: row = Vec4(0.0f, scale, 0.0f, minBias); break; 586 case 2: row = Vec4(-scale, 0.0f, 0.0f, maxBias); break; 587 case 3: row = Vec4(0.0f, -scale, 0.0f, maxBias); break; 588 default: DE_ASSERT(false); 589 } 590 591 attribMatrix.setRow(rowNdx, row); 592 } 593 594 m_userAttribTransforms[inputNdx] = attribMatrix; 595 } 596 } 597 598 ShaderOperatorCase::~ShaderOperatorCase (void) 599 { 600 } 601 602 // ShaderOperatorTests. 603 604 ShaderOperatorTests::ShaderOperatorTests(Context& context) 605 : TestCaseGroup(context, "operator", "Operator tests.") 606 { 607 } 608 609 ShaderOperatorTests::~ShaderOperatorTests (void) 610 { 611 } 612 613 // Vector math functions. 614 template<typename T> inline T nop (T f) { return f; } 615 616 template <typename T, int Size> 617 Vector<T, Size> nop (const Vector<T, Size>& v) { return v; } 618 619 #define DECLARE_UNARY_GENTYPE_FUNCS(FUNC_NAME) \ 620 void eval_##FUNC_NAME##_float (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(2)).x(); } \ 621 void eval_##FUNC_NAME##_vec2 (ShaderEvalContext& c) { c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1)); } \ 622 void eval_##FUNC_NAME##_vec3 (ShaderEvalContext& c) { c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1)); } \ 623 void eval_##FUNC_NAME##_vec4 (ShaderEvalContext& c) { c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); } 624 625 #define DECLARE_BINARY_GENTYPE_FUNCS(FUNC_NAME) \ 626 void eval_##FUNC_NAME##_float (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0)).x(); } \ 627 void eval_##FUNC_NAME##_vec2 (ShaderEvalContext& c) { c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); } \ 628 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)); } \ 629 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)); } 630 631 #define DECLARE_TERNARY_GENTYPE_FUNCS(FUNC_NAME) \ 632 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(); } \ 633 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)); } \ 634 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)); } \ 635 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)); } 636 637 #define DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME) \ 638 void eval_##FUNC_NAME##_float (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(2)); } \ 639 void eval_##FUNC_NAME##_vec2 (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(3, 1)); } \ 640 void eval_##FUNC_NAME##_vec3 (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(2, 0, 1)); } \ 641 void eval_##FUNC_NAME##_vec4 (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0)); } 642 643 #define DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(FUNC_NAME) \ 644 void eval_##FUNC_NAME##_float (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(2), c.in[1].swizzle(0)); } \ 645 void eval_##FUNC_NAME##_vec2 (ShaderEvalContext& c) { c.color.x() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].swizzle(1, 0)); } \ 646 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)); } \ 647 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)); } 648 649 #define DECLARE_BINARY_BOOL_FUNCS(FUNC_NAME) \ 650 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); } 651 652 #define DECLARE_UNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME) \ 653 void eval_##FUNC_NAME##_bool (ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].z() > 0.0f); } \ 654 void eval_##FUNC_NAME##_bvec2 (ShaderEvalContext& c) { c.color.yz() = FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); } \ 655 void eval_##FUNC_NAME##_bvec3 (ShaderEvalContext& c) { c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); } \ 656 void eval_##FUNC_NAME##_bvec4 (ShaderEvalContext& c) { c.color = FUNC_NAME(greaterThan(c.in[0].swizzle(1, 2, 3, 0), Vec4(0.0f))).asFloat(); } 657 658 #define DECLARE_TERNARY_BOOL_GENTYPE_FUNCS(FUNC_NAME) \ 659 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); } \ 660 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(); } \ 661 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(); } \ 662 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(); } 663 664 #define DECLARE_UNARY_INT_GENTYPE_FUNCS(FUNC_NAME) \ 665 void eval_##FUNC_NAME##_int (ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME((int)c.in[0].z()); } \ 666 void eval_##FUNC_NAME##_ivec2 (ShaderEvalContext& c) { c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1).asInt()).asFloat(); } \ 667 void eval_##FUNC_NAME##_ivec3 (ShaderEvalContext& c) { c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1).asInt()).asFloat(); } \ 668 void eval_##FUNC_NAME##_ivec4 (ShaderEvalContext& c) { c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0).asInt()).asFloat(); } 669 670 #define DECLARE_BINARY_INT_GENTYPE_FUNCS(FUNC_NAME) \ 671 void eval_##FUNC_NAME##_int (ShaderEvalContext& c) { c.color.x() = (float)tcu::FUNC_NAME((int)c.in[0].z(), (int)c.in[1].x()); } \ 672 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(); } \ 673 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(); } \ 674 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(); } 675 676 #define DECLARE_TERNARY_INT_GENTYPE_FUNCS(FUNC_NAME) \ 677 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()); } \ 678 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(); } \ 679 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(); } \ 680 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(); } 681 682 #define DECLARE_VEC_FLOAT_FUNCS(FUNC_NAME) \ 683 void eval_##FUNC_NAME##_vec2 (ShaderEvalContext& c) { c.color.yz() = FUNC_NAME(c.in[0].swizzle(3, 1), c.in[1].x()); } \ 684 void eval_##FUNC_NAME##_vec3 (ShaderEvalContext& c) { c.color.xyz() = FUNC_NAME(c.in[0].swizzle(2, 0, 1), c.in[1].x()); } \ 685 void eval_##FUNC_NAME##_vec4 (ShaderEvalContext& c) { c.color = FUNC_NAME(c.in[0].swizzle(1, 2, 3, 0), c.in[1].x()); } 686 687 #define DECLARE_VEC_FLOAT_FLOAT_FUNCS(FUNC_NAME) \ 688 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()); } \ 689 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()); } \ 690 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()); } 691 692 #define DECLARE_VEC_VEC_FLOAT_FUNCS(FUNC_NAME) \ 693 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()); } \ 694 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()); } \ 695 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()); } 696 697 #define DECLARE_FLOAT_FLOAT_VEC_FUNCS(FUNC_NAME) \ 698 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)); } \ 699 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)); } \ 700 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)); } 701 702 #define DECLARE_FLOAT_VEC_FUNCS(FUNC_NAME) \ 703 void eval_##FUNC_NAME##_vec2 (ShaderEvalContext& c) { c.color.yz() = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(1, 0)); } \ 704 void eval_##FUNC_NAME##_vec3 (ShaderEvalContext& c) { c.color.xyz() = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(1, 2, 0)); } \ 705 void eval_##FUNC_NAME##_vec4 (ShaderEvalContext& c) { c.color = FUNC_NAME(c.in[0].z(), c.in[1].swizzle(3, 2, 1, 0)); } 706 707 #define DECLARE_IVEC_INT_FUNCS(FUNC_NAME) \ 708 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(); } \ 709 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(); } \ 710 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(); } 711 712 #define DECLARE_INT_IVEC_FUNCS(FUNC_NAME) \ 713 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(); } \ 714 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(); } \ 715 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(); } 716 717 // Operators. 718 719 DECLARE_UNARY_GENTYPE_FUNCS(nop) 720 DECLARE_UNARY_GENTYPE_FUNCS(negate) 721 DECLARE_UNARY_GENTYPE_FUNCS(addOne) 722 DECLARE_UNARY_GENTYPE_FUNCS(subOne) 723 DECLARE_BINARY_GENTYPE_FUNCS(add) 724 DECLARE_BINARY_GENTYPE_FUNCS(sub) 725 DECLARE_BINARY_GENTYPE_FUNCS(mul) 726 DECLARE_BINARY_GENTYPE_FUNCS(div) 727 728 void eval_selection_float (ShaderEvalContext& c) { c.color.x() = selection(c.in[0].z() > 0.0f, c.in[1].x(), c.in[2].y()); } 729 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)); } 730 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)); } 731 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)); } 732 733 DECLARE_UNARY_INT_GENTYPE_FUNCS(nop) 734 DECLARE_UNARY_INT_GENTYPE_FUNCS(negate) 735 DECLARE_UNARY_INT_GENTYPE_FUNCS(addOne) 736 DECLARE_UNARY_INT_GENTYPE_FUNCS(subOne) 737 DECLARE_BINARY_INT_GENTYPE_FUNCS(add) 738 DECLARE_BINARY_INT_GENTYPE_FUNCS(sub) 739 DECLARE_BINARY_INT_GENTYPE_FUNCS(mul) 740 DECLARE_BINARY_INT_GENTYPE_FUNCS(div) 741 742 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()); } 743 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(); } 744 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(); } 745 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(); } 746 747 DECLARE_UNARY_BOOL_GENTYPE_FUNCS(boolNot) 748 DECLARE_BINARY_BOOL_FUNCS(logicalAnd) 749 DECLARE_BINARY_BOOL_FUNCS(logicalOr) 750 DECLARE_BINARY_BOOL_FUNCS(logicalXor) 751 752 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); } 753 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(); } 754 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(); } 755 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(); } 756 757 DECLARE_VEC_FLOAT_FUNCS(addVecScalar) 758 DECLARE_VEC_FLOAT_FUNCS(subVecScalar) 759 DECLARE_VEC_FLOAT_FUNCS(mulVecScalar) 760 DECLARE_VEC_FLOAT_FUNCS(divVecScalar) 761 762 DECLARE_FLOAT_VEC_FUNCS(addScalarVec) 763 DECLARE_FLOAT_VEC_FUNCS(subScalarVec) 764 DECLARE_FLOAT_VEC_FUNCS(mulScalarVec) 765 DECLARE_FLOAT_VEC_FUNCS(divScalarVec) 766 767 DECLARE_IVEC_INT_FUNCS(addVecScalar) 768 DECLARE_IVEC_INT_FUNCS(subVecScalar) 769 DECLARE_IVEC_INT_FUNCS(mulVecScalar) 770 DECLARE_IVEC_INT_FUNCS(divVecScalar) 771 772 DECLARE_INT_IVEC_FUNCS(addScalarVec) 773 DECLARE_INT_IVEC_FUNCS(subScalarVec) 774 DECLARE_INT_IVEC_FUNCS(mulScalarVec) 775 DECLARE_INT_IVEC_FUNCS(divScalarVec) 776 777 // Built-in functions. 778 779 DECLARE_UNARY_GENTYPE_FUNCS(radians) 780 DECLARE_UNARY_GENTYPE_FUNCS(degrees) 781 DECLARE_UNARY_GENTYPE_FUNCS(sin) 782 DECLARE_UNARY_GENTYPE_FUNCS(cos) 783 DECLARE_UNARY_GENTYPE_FUNCS(tan) 784 DECLARE_UNARY_GENTYPE_FUNCS(asin) 785 DECLARE_UNARY_GENTYPE_FUNCS(acos) 786 DECLARE_UNARY_GENTYPE_FUNCS(atan) 787 DECLARE_BINARY_GENTYPE_FUNCS(atan2) 788 789 DECLARE_BINARY_GENTYPE_FUNCS(pow) 790 DECLARE_UNARY_GENTYPE_FUNCS(exp) 791 DECLARE_UNARY_GENTYPE_FUNCS(log) 792 DECLARE_UNARY_GENTYPE_FUNCS(exp2) 793 DECLARE_UNARY_GENTYPE_FUNCS(log2) 794 DECLARE_UNARY_GENTYPE_FUNCS(sqrt) 795 DECLARE_UNARY_GENTYPE_FUNCS(inverseSqrt) 796 797 DECLARE_UNARY_GENTYPE_FUNCS(abs) 798 DECLARE_UNARY_GENTYPE_FUNCS(sign) 799 DECLARE_UNARY_GENTYPE_FUNCS(floor) 800 DECLARE_UNARY_GENTYPE_FUNCS(ceil) 801 DECLARE_UNARY_GENTYPE_FUNCS(fract) 802 DECLARE_BINARY_GENTYPE_FUNCS(mod) 803 DECLARE_VEC_FLOAT_FUNCS(modVecFloat) 804 DECLARE_BINARY_GENTYPE_FUNCS(min) 805 DECLARE_VEC_FLOAT_FUNCS(minVecFloat) 806 DECLARE_BINARY_GENTYPE_FUNCS(max) 807 DECLARE_VEC_FLOAT_FUNCS(maxVecFloat) 808 DECLARE_TERNARY_GENTYPE_FUNCS(clamp) 809 DECLARE_VEC_FLOAT_FLOAT_FUNCS(clampVecFloatFloat) 810 DECLARE_TERNARY_GENTYPE_FUNCS(mix) 811 DECLARE_VEC_VEC_FLOAT_FUNCS(mixVecVecFloat) 812 DECLARE_BINARY_GENTYPE_FUNCS(step) 813 DECLARE_FLOAT_VEC_FUNCS(stepFloatVec) 814 DECLARE_TERNARY_GENTYPE_FUNCS(smoothStep) 815 DECLARE_FLOAT_FLOAT_VEC_FUNCS(smoothStepFloatFloatVec) 816 817 DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(length) 818 DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(distance) 819 DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(dot) 820 void eval_cross_vec3 (ShaderEvalContext& c) { c.color.xyz() = cross(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); } 821 822 DECLARE_UNARY_GENTYPE_FUNCS(normalize) 823 DECLARE_TERNARY_GENTYPE_FUNCS(faceForward) 824 DECLARE_BINARY_GENTYPE_FUNCS(reflect) 825 826 void eval_refract_float (ShaderEvalContext& c) { c.color.x() = refract(c.in[0].z(), c.in[1].x(), c.in[2].y()); } 827 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()); } 828 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()); } 829 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()); } 830 831 // Compare functions. 832 833 #define DECLARE_FLOAT_COMPARE_FUNCS(FUNC_NAME) \ 834 void eval_##FUNC_NAME##_float (ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].z(), c.in[1].x()); } \ 835 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)); } \ 836 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)); } \ 837 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)); } 838 839 #define DECLARE_FLOAT_CWISE_COMPARE_FUNCS(FUNC_NAME) \ 840 void eval_##FUNC_NAME##_float (ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(c.in[0].z(), c.in[1].x()); } \ 841 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(); } \ 842 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(); } \ 843 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(); } 844 845 #define DECLARE_INT_COMPARE_FUNCS(FUNC_NAME) \ 846 void eval_##FUNC_NAME##_int (ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); } \ 847 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))); } \ 848 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))); } \ 849 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))); } 850 851 #define DECLARE_INT_CWISE_COMPARE_FUNCS(FUNC_NAME) \ 852 void eval_##FUNC_NAME##_int (ShaderEvalContext& c) { c.color.x() = (float)FUNC_NAME(chopToInt(c.in[0].z()), chopToInt(c.in[1].x())); } \ 853 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(); } \ 854 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(); } \ 855 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(); } 856 857 #define DECLARE_BOOL_COMPARE_FUNCS(FUNC_NAME) \ 858 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); } \ 859 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))); } \ 860 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))); } \ 861 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))); } 862 863 #define DECLARE_BOOL_CWISE_COMPARE_FUNCS(FUNC_NAME) \ 864 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); } \ 865 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(); } \ 866 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(); } \ 867 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(); } 868 869 DECLARE_FLOAT_COMPARE_FUNCS(allEqual) 870 DECLARE_FLOAT_COMPARE_FUNCS(anyNotEqual) 871 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThan) 872 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThanEqual) 873 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThan) 874 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThanEqual) 875 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(equal) 876 DECLARE_FLOAT_CWISE_COMPARE_FUNCS(notEqual) 877 878 DECLARE_INT_COMPARE_FUNCS(allEqual) 879 DECLARE_INT_COMPARE_FUNCS(anyNotEqual) 880 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThan) 881 DECLARE_INT_CWISE_COMPARE_FUNCS(lessThanEqual) 882 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThan) 883 DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThanEqual) 884 DECLARE_INT_CWISE_COMPARE_FUNCS(equal) 885 DECLARE_INT_CWISE_COMPARE_FUNCS(notEqual) 886 887 DECLARE_BOOL_COMPARE_FUNCS(allEqual) 888 DECLARE_BOOL_COMPARE_FUNCS(anyNotEqual) 889 DECLARE_BOOL_CWISE_COMPARE_FUNCS(equal) 890 DECLARE_BOOL_CWISE_COMPARE_FUNCS(notEqual) 891 892 // Boolean functions. 893 894 #define DECLARE_UNARY_SCALAR_BVEC_FUNCS(GLSL_NAME, FUNC_NAME) \ 895 void eval_##GLSL_NAME##_bvec2 (ShaderEvalContext& c) { c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f)))); } \ 896 void eval_##GLSL_NAME##_bvec3 (ShaderEvalContext& c) { c.color.x() = float(FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f)))); } \ 897 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)))); } 898 899 #define DECLARE_UNARY_BVEC_BVEC_FUNCS(GLSL_NAME, FUNC_NAME) \ 900 void eval_##GLSL_NAME##_bvec2 (ShaderEvalContext& c) { c.color.yz() = FUNC_NAME(greaterThan(c.in[0].swizzle(3, 1), Vec2(0.0f))).asFloat(); } \ 901 void eval_##GLSL_NAME##_bvec3 (ShaderEvalContext& c) { c.color.xyz() = FUNC_NAME(greaterThan(c.in[0].swizzle(2, 0, 1), Vec3(0.0f))).asFloat(); } \ 902 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(); } 903 904 DECLARE_UNARY_SCALAR_BVEC_FUNCS(any, boolAny); 905 DECLARE_UNARY_SCALAR_BVEC_FUNCS(all, boolAll); 906 907 void ShaderOperatorTests::init (void) 908 { 909 // Requisites: 910 // - input types (const, uniform, dynamic, mixture) 911 // - data types (bool, int, float, vecs, mats) 912 // - 913 // - complex expressions (\todo [petri] move to expressions?) 914 // * early-exit from side effects 915 // * precedence 916 917 // unary plus, minus 918 // add, sub 919 // mul (larger range) 920 // div (div-by-zero) 921 // incr, decr (int only) 922 // relational 923 // equality 924 // logical 925 // selection 926 // assignment 927 // arithmetic assignment 928 929 // parenthesis 930 // sequence 931 // subscript, function call, field selector/swizzler 932 933 // precedence 934 // data types (float, int, bool, vecs, matrices) 935 936 // TestCaseGroup* group = new TestCaseGroup(m_testCtx, "additive", "Additive operator tests."); 937 // addChild(group); 938 939 // * * * 940 941 // Built-in functions 942 // - precision, data types 943 944 #define BOOL_FUNCS(FUNC_NAME) eval_##FUNC_NAME##_bool, DE_NULL, DE_NULL, DE_NULL 945 946 #define FLOAT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4 947 #define INT_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4 948 #define BOOL_VEC_FUNCS(FUNC_NAME) DE_NULL, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4 949 950 #define FLOAT_GENTYPE_FUNCS(FUNC_NAME) eval_##FUNC_NAME##_float, eval_##FUNC_NAME##_vec2, eval_##FUNC_NAME##_vec3, eval_##FUNC_NAME##_vec4 951 #define INT_GENTYPE_FUNCS(FUNC_NAME) eval_##FUNC_NAME##_int, eval_##FUNC_NAME##_ivec2, eval_##FUNC_NAME##_ivec3, eval_##FUNC_NAME##_ivec4 952 #define BOOL_GENTYPE_FUNCS(FUNC_NAME) eval_##FUNC_NAME##_bool, eval_##FUNC_NAME##_bvec2, eval_##FUNC_NAME##_bvec3, eval_##FUNC_NAME##_bvec4 953 954 Value notUsed = Value(VALUE_NONE, 0.0f, 0.0f); 955 956 std::vector<BuiltinFuncGroup> funcInfoGroups; 957 958 // Unary operators. 959 funcInfoGroups.push_back( 960 BuiltinFuncGroup("unary_operator", "Unary operator tests") 961 << BuiltinOperInfo("plus", "+", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(nop)) 962 << BuiltinOperInfo("plus", "+", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(nop)) 963 << BuiltinOperInfo("minus", "-", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(negate)) 964 << BuiltinOperInfo("minus", "-", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(negate)) 965 << 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) 966 967 // Pre/post incr/decr side effect cases. 968 << BuiltinSideEffOperInfo ("pre_increment_effect", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne)) 969 << BuiltinSideEffOperInfo ("pre_increment_effect", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne)) 970 << BuiltinSideEffOperInfo ("pre_decrement_effect", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 1.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne)) 971 << BuiltinSideEffOperInfo ("pre_decrement_effect", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne)) 972 << BuiltinPostSideEffOperInfo ("post_increment_effect", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne)) 973 << BuiltinPostSideEffOperInfo ("post_increment_effect", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne)) 974 << BuiltinPostSideEffOperInfo ("post_decrement_effect", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 1.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne)) 975 << BuiltinPostSideEffOperInfo ("post_decrement_effect", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne)) 976 977 // Pre/post incr/decr result cases. 978 << BuiltinOperInfo ("pre_increment_result", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(addOne)) 979 << BuiltinOperInfo ("pre_increment_result", "++", IGT, Value(IGT, -6.0f, 4.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(addOne)) 980 << BuiltinOperInfo ("pre_decrement_result", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 1.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(subOne)) 981 << BuiltinOperInfo ("pre_decrement_result", "--", IGT, Value(IGT, -4.0f, 6.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(subOne)) 982 << BuiltinPostOperInfo ("post_increment_result", "++", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(nop)) 983 << BuiltinPostOperInfo ("post_increment_result", "++", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(nop)) 984 << BuiltinPostOperInfo ("post_decrement_result", "--", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(nop)) 985 << BuiltinPostOperInfo ("post_decrement_result", "--", IGT, Value(IGT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(nop)) 986 ); 987 988 // Binary operators. 989 funcInfoGroups.push_back( 990 BuiltinFuncGroup("binary_operator", "Binary operator tests") 991 // Arithmetic operators. 992 << BuiltinOperInfo("add", "+", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(add)) 993 << BuiltinOperInfo("add", "+", IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(add)) 994 << BuiltinOperInfo("add", "+", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addVecScalar)) 995 << BuiltinOperInfo("add", "+", IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(addVecScalar)) 996 << BuiltinOperInfo("add", "+", FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addScalarVec)) 997 << BuiltinOperInfo("add", "+", IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(addScalarVec)) 998 << BuiltinOperInfo("sub", "-", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(sub)) 999 << BuiltinOperInfo("sub", "-", IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(sub)) 1000 << BuiltinOperInfo("sub", "-", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subVecScalar)) 1001 << BuiltinOperInfo("sub", "-", IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(subVecScalar)) 1002 << BuiltinOperInfo("sub", "-", FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subScalarVec)) 1003 << BuiltinOperInfo("sub", "-", IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(subScalarVec)) 1004 << BuiltinOperInfo("mul", "*", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(mul)) 1005 << BuiltinOperInfo("mul", "*", IGT, Value(IGT, -4.0f, 6.0f), Value(IGT, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(mul)) 1006 << BuiltinOperInfo("mul", "*", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulVecScalar)) 1007 << BuiltinOperInfo("mul", "*", IV, Value(IV, -4.0f, 6.0f), Value(I, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(mulVecScalar)) 1008 << BuiltinOperInfo("mul", "*", FV, Value(F, -1.0f, 1.0f), Value(FV, -1.0f, 1.0f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulScalarVec)) 1009 << BuiltinOperInfo("mul", "*", IV, Value(I, -4.0f, 6.0f), Value(IV, -6.0f, 5.0f), notUsed, 0.1f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(mulScalarVec)) 1010 << BuiltinOperInfo("div", "/", GT, Value(GT, -1.0f, 1.0f), Value(GT, -2.0f, -0.5f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(div)) 1011 << BuiltinOperInfo("div", "/", IGT, Value(IGT, 24.0f, 24.0f), Value(IGT, -4.0f, -1.0f), notUsed, 0.04f, 1.0f, PRECMASK_ALL, INT_GENTYPE_FUNCS(div)) 1012 << BuiltinOperInfo("div", "/", FV, Value(FV, -1.0f, 1.0f), Value(F, -2.0f, -0.5f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divVecScalar)) 1013 << BuiltinOperInfo("div", "/", IV, Value(IV, 24.0f, 24.0f), Value(I, -4.0f, -1.0f), notUsed, 0.04f, 1.0f, PRECMASK_ALL, INT_VEC_FUNCS(divVecScalar)) 1014 << BuiltinOperInfo("div", "/", FV, Value(F, -1.0f, 1.0f), Value(FV, -2.0f, -0.5f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divScalarVec)) 1015 << BuiltinOperInfo("div", "/", IV, Value(I, 24.0f, 24.0f), Value(IV, -4.0f, -1.0f), notUsed, 0.04f, 1.0f, PRECMASK_ALL, INT_VEC_FUNCS(divScalarVec)) 1016 1017 // Arithmetic assignment side effect cases. 1018 << BuiltinSideEffOperInfo ("add_assign_effect", "+=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(add)) 1019 << BuiltinSideEffOperInfo ("add_assign_effect", "+=", IGT, Value(IGT, -5.0f, 5.0f), Value(IGT, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(add)) 1020 << BuiltinSideEffOperInfo ("add_assign_effect", "+=", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addVecScalar)) 1021 << BuiltinSideEffOperInfo ("add_assign_effect", "+=", IV, Value(IV, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(addVecScalar)) 1022 << BuiltinSideEffOperInfo ("sub_assign_effect", "-=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(sub)) 1023 << BuiltinSideEffOperInfo ("sub_assign_effect", "-=", IGT, Value(IGT, -5.0f, 5.0f), Value(IGT, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(sub)) 1024 << BuiltinSideEffOperInfo ("sub_assign_effect", "-=", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subVecScalar)) 1025 << BuiltinSideEffOperInfo ("sub_assign_effect", "-=", IV, Value(IV, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(subVecScalar)) 1026 << BuiltinSideEffOperInfo ("mul_assign_effect", "*=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(mul)) 1027 << BuiltinSideEffOperInfo ("mul_assign_effect", "*=", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -4.0f, 4.0f), notUsed, 0.03f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(mul)) 1028 << BuiltinSideEffOperInfo ("mul_assign_effect", "*=", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulVecScalar)) 1029 << BuiltinSideEffOperInfo ("mul_assign_effect", "*=", IV, Value(IV, -4.0f, 4.0f), Value(I, -4.0f, 4.0f), notUsed, 0.03f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(mulVecScalar)) 1030 << BuiltinSideEffOperInfo ("div_assign_effect", "/=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -2.0f, -0.5f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(div)) 1031 << BuiltinSideEffOperInfo ("div_assign_effect", "/=", IGT, Value(IGT, 24.0f, 24.0f), Value(IGT, -4.0f, -1.0f), notUsed, 0.04f, 1.0f, PRECMASK_ALL, INT_GENTYPE_FUNCS(div)) 1032 << BuiltinSideEffOperInfo ("div_assign_effect", "/=", FV, Value(FV, -1.0f, 1.0f), Value(F, -2.0f, -0.5f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divVecScalar)) 1033 << BuiltinSideEffOperInfo ("div_assign_effect", "/=", IV, Value(IV, 24.0f, 24.0f), Value(I, -4.0f, -1.0f), notUsed, 0.04f, 1.0f, PRECMASK_ALL, INT_VEC_FUNCS(divVecScalar)) 1034 1035 // Arithmetic assignment result cases. 1036 << BuiltinOperInfo ("add_assign_result", "+=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(add)) 1037 << BuiltinOperInfo ("add_assign_result", "+=", IGT, Value(IGT, -5.0f, 5.0f), Value(IGT, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(add)) 1038 << BuiltinOperInfo ("add_assign_result", "+=", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(addVecScalar)) 1039 << BuiltinOperInfo ("add_assign_result", "+=", IV, Value(IV, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(addVecScalar)) 1040 << BuiltinOperInfo ("sub_assign_result", "-=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(sub)) 1041 << BuiltinOperInfo ("sub_assign_result", "-=", IGT, Value(IGT, -5.0f, 5.0f), Value(IGT, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(sub)) 1042 << BuiltinOperInfo ("sub_assign_result", "-=", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(subVecScalar)) 1043 << BuiltinOperInfo ("sub_assign_result", "-=", IV, Value(IV, -5.0f, 5.0f), Value(I, -5.0f, 5.0f), notUsed, 0.05f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(subVecScalar)) 1044 << BuiltinOperInfo ("mul_assign_result", "*=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -1.0f, 1.0f), notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(mul)) 1045 << BuiltinOperInfo ("mul_assign_result", "*=", IGT, Value(IGT, -4.0f, 4.0f), Value(IGT, -4.0f, 4.0f), notUsed, 0.03f, 0.5f, PRECMASK_ALL, INT_GENTYPE_FUNCS(mul)) 1046 << BuiltinOperInfo ("mul_assign_result", "*=", FV, Value(FV, -1.0f, 1.0f), Value(F, -1.0f, 1.0f), notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(mulVecScalar)) 1047 << BuiltinOperInfo ("mul_assign_result", "*=", IV, Value(IV, -4.0f, 4.0f), Value(I, -4.0f, 4.0f), notUsed, 0.03f, 0.5f, PRECMASK_ALL, INT_VEC_FUNCS(mulVecScalar)) 1048 << BuiltinOperInfo ("div_assign_result", "/=", GT, Value(GT, -1.0f, 1.0f), Value(GT, -2.0f, -0.5f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(div)) 1049 << BuiltinOperInfo ("div_assign_result", "/=", IGT, Value(IGT, 24.0f, 24.0f), Value(IGT, -4.0f, -1.0f), notUsed, 0.04f, 1.0f, PRECMASK_ALL, INT_GENTYPE_FUNCS(div)) 1050 << BuiltinOperInfo ("div_assign_result", "/=", FV, Value(FV, -1.0f, 1.0f), Value(F, -2.0f, -0.5f), notUsed, 0.25f, 0.5f, PRECMASK_ALL, FLOAT_VEC_FUNCS(divVecScalar)) 1051 << BuiltinOperInfo ("div_assign_result", "/=", IV, Value(IV, 24.0f, 24.0f), Value(I, -4.0f, -1.0f), notUsed, 0.04f, 1.0f, PRECMASK_ALL, INT_VEC_FUNCS(divVecScalar)) 1052 1053 // Scalar relational operators. 1054 << 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) 1055 << 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) 1056 << 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) 1057 << 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) 1058 << 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) 1059 << 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) 1060 << 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) 1061 << 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) 1062 1063 // Equality comparison operators. 1064 << 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)) 1065 << BuiltinOperInfo("equal", "==", B, Value(IGT, -5.5f, 4.7f), Value(IGT, -4.9f, 5.8f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, INT_GENTYPE_FUNCS(allEqual)) 1066 << 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)) 1067 << 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)) 1068 << BuiltinOperInfo("not_equal", "!=", B, Value(IGT, -5.5f, 4.7f), Value(IGT, -4.9f, 5.8f), notUsed, 1.0f, 0.0f, PRECMASK_ALL, INT_GENTYPE_FUNCS(anyNotEqual)) 1069 << 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)) 1070 1071 // Logical operators. 1072 << 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)) 1073 << 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)) 1074 << 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)) 1075 ); 1076 1077 // 8.1 Angle and Trigonometry Functions. 1078 funcInfoGroups.push_back( 1079 BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.") 1080 << BuiltinFuncInfo("radians", "radians", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 25.0f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(radians) ) 1081 << BuiltinFuncInfo("degrees", "degrees", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 0.04f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(degrees) ) 1082 << BuiltinFuncInfo("sin", "sin", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(sin) ) 1083 << BuiltinFuncInfo("sin", "sin", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(sin) ) 1084 << BuiltinFuncInfo("cos", "cos", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(cos) ) 1085 << BuiltinFuncInfo("cos", "cos", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(cos) ) 1086 << BuiltinFuncInfo("tan", "tan", GT, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(tan) ) 1087 << BuiltinFuncInfo("tan", "tan", GT, Value(GT, -1.5f, 5.5f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_LOWP, FLOAT_GENTYPE_FUNCS(tan) ) 1088 << BuiltinFuncInfo("asin", "asin", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(asin) ) 1089 << BuiltinFuncInfo("acos", "acos", GT, Value(GT, -1.0f, 1.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(acos) ) 1090 << BuiltinFuncInfo("atan", "atan", GT, Value(GT, -4.0f, 4.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(atan) ) 1091 << 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) ) 1092 ); 1093 1094 // 8.2 Exponential Functions. 1095 funcInfoGroups.push_back( 1096 BuiltinFuncGroup("exponential", "Exponential function tests") 1097 << 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) ) 1098 << BuiltinFuncInfo("exp", "exp", GT, Value(GT, -6.0f, 3.0f), notUsed, notUsed, 0.5f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(exp) ) 1099 << BuiltinFuncInfo("log", "log", GT, Value(GT, 0.1f, 10.0f), notUsed, notUsed, 0.5f, 0.3f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(log) ) 1100 << BuiltinFuncInfo("exp2", "exp2", GT, Value(GT, -7.0f, 2.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(exp2) ) 1101 << BuiltinFuncInfo("log2", "log2", GT, Value(GT, 0.1f, 10.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(log2) ) 1102 << BuiltinFuncInfo("sqrt", "sqrt", GT, Value(GT, 0.0f, 10.0f), notUsed, notUsed, 0.3f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(sqrt) ) 1103 << BuiltinFuncInfo("inversesqrt", "inversesqrt", GT, Value(GT, 0.5f, 10.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(inverseSqrt) ) 1104 ); 1105 1106 // 8.3 Common Functions. 1107 funcInfoGroups.push_back( 1108 BuiltinFuncGroup("common_functions", "Common function tests.") 1109 << BuiltinFuncInfo("abs", "abs", GT, Value(GT, -2.0f, 2.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(abs) ) 1110 << BuiltinFuncInfo("sign", "sign", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.3f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(sign) ) 1111 << BuiltinFuncInfo("floor", "floor", GT, Value(GT, -2.5f, 2.5f), notUsed, notUsed, 0.2f, 0.7f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(floor) ) 1112 << BuiltinFuncInfo("ceil", "ceil", GT, Value(GT, -2.5f, 2.5f), notUsed, notUsed, 0.2f, 0.5f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(ceil) ) 1113 << BuiltinFuncInfo("fract", "fract", GT, Value(GT, -1.5f, 1.5f), notUsed, notUsed, 0.8f, 0.1f, PRECMASK_ALL, FLOAT_GENTYPE_FUNCS(fract) ) 1114 << 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) ) 1115 << 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(modVecFloat) ) 1116 << 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) ) 1117 << 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(minVecFloat) ) 1118 << 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) ) 1119 << 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(maxVecFloat) ) 1120 << 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) ) 1121 << 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(clampVecFloatFloat) ) 1122 << 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) ) 1123 << 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(mixVecVecFloat) ) 1124 << 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) ) 1125 << 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(stepFloatVec) ) 1126 << 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) ) 1127 << 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(smoothStepFloatFloatVec) ) 1128 ); 1129 1130 // 8.4 Geometric Functions. 1131 funcInfoGroups.push_back( 1132 BuiltinFuncGroup("geometric", "Geometric function tests.") 1133 << BuiltinFuncInfo("length", "length", F, Value(GT, -5.0f, 5.0f), notUsed, notUsed, 0.1f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(length) ) 1134 << 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) ) 1135 << 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) ) 1136 << 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 ) 1137 << BuiltinFuncInfo("normalize", "normalize", GT, Value(GT, 0.1f, 4.0f), notUsed, notUsed, 0.5f, 0.5f, PRECMASK_MEDIUMP_HIGHP, FLOAT_GENTYPE_FUNCS(normalize) ) 1138 << 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) ) 1139 << 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) ) 1140 << 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) ) 1141 ); 1142 1143 // 8.5 Matrix Functions. 1144 // separate matrix tests? 1145 // funcInfoGroups.push_back( 1146 // BuiltinFuncGroup("matrix", "Matrix function tests.") 1147 // << BuiltinFuncInfo("matrixCompMult", "matrixCompMult", M, ... ) 1148 // ); 1149 1150 // 8.6 Vector Relational Functions. 1151 funcInfoGroups.push_back( 1152 BuiltinFuncGroup("float_compare", "Floating point comparison tests.") 1153 << 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) ) 1154 << 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) ) 1155 << 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) ) 1156 << 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) ) 1157 << 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) ) 1158 << 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) ) 1159 ); 1160 1161 funcInfoGroups.push_back( 1162 BuiltinFuncGroup("int_compare", "Integer comparison tests.") 1163 << 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) ) 1164 << 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) ) 1165 << 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) ) 1166 << 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) ) 1167 << 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) ) 1168 << 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) ) 1169 ); 1170 1171 funcInfoGroups.push_back( 1172 BuiltinFuncGroup("bool_compare", "Boolean comparison tests.") 1173 << 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) ) 1174 << 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) ) 1175 << BuiltinFuncInfo("any", "any", B, Value(BV, -1.0f, 0.3f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_NA, BOOL_VEC_FUNCS(any) ) 1176 << BuiltinFuncInfo("all", "all", B, Value(BV, -0.3f, 1.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_NA, BOOL_VEC_FUNCS(all) ) 1177 << BuiltinFuncInfo("not", "not", BV, Value(BV, -1.0f, 1.0f), notUsed, notUsed, 1.0f, 0.0f, PRECMASK_NA, BOOL_VEC_FUNCS(boolNot) ) 1178 ); 1179 1180 // 8.7 Texture Lookup Functions 1181 // texture2D (sampler, vec2) 1182 // texture2D (sampler, vec2, bias) 1183 // texture2DProj (sampler, vec3) 1184 // texture2DProj (sampler, vec3, bias) 1185 // texture2DProj (sampler, vec4) 1186 // texture2DProj (sampler, vec4, bias) 1187 // texture2DLod (sampler, vec2, lod) 1188 // texture2DProjLod (sampler, vec3, lod) 1189 // texture2DProjLod (sampler, vec4, lod) 1190 // textureCube (sampler, vec3) 1191 // textureCube (sampler, vec3, bias) 1192 // textureCubeLod (sampler, vec3, lod) 1193 1194 static const ShaderType s_shaderTypes[] = 1195 { 1196 SHADERTYPE_VERTEX, 1197 SHADERTYPE_FRAGMENT 1198 }; 1199 1200 static const DataType s_floatTypes[] = 1201 { 1202 TYPE_FLOAT, 1203 TYPE_FLOAT_VEC2, 1204 TYPE_FLOAT_VEC3, 1205 TYPE_FLOAT_VEC4 1206 }; 1207 1208 static const DataType s_intTypes[] = 1209 { 1210 TYPE_INT, 1211 TYPE_INT_VEC2, 1212 TYPE_INT_VEC3, 1213 TYPE_INT_VEC4 1214 }; 1215 1216 static const DataType s_boolTypes[] = 1217 { 1218 TYPE_BOOL, 1219 TYPE_BOOL_VEC2, 1220 TYPE_BOOL_VEC3, 1221 TYPE_BOOL_VEC4 1222 }; 1223 1224 for (int outerGroupNdx = 0; outerGroupNdx < (int)funcInfoGroups.size(); outerGroupNdx++) 1225 { 1226 // Create outer group. 1227 const BuiltinFuncGroup& outerGroupInfo = funcInfoGroups[outerGroupNdx]; 1228 TestCaseGroup* outerGroup = new TestCaseGroup(m_context, outerGroupInfo.name, outerGroupInfo.description); 1229 addChild(outerGroup); 1230 1231 // Only create new group if name differs from previous one. 1232 TestCaseGroup* innerGroup = DE_NULL; 1233 1234 for (int funcInfoNdx = 0; funcInfoNdx < (int)outerGroupInfo.funcInfos.size(); funcInfoNdx++) 1235 { 1236 const BuiltinFuncInfo& funcInfo = outerGroupInfo.funcInfos[funcInfoNdx]; 1237 const char* shaderFuncName = funcInfo.shaderFuncName; 1238 bool isBoolCase = (funcInfo.precisionMask == PRECMASK_NA); 1239 bool isIntCase = (funcInfo.input0.valueType & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0; 1240 bool isFloatCase = !isBoolCase && !isIntCase; // \todo [petri] Better check. 1241 bool isBoolOut = (funcInfo.outValue & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0; 1242 bool isIntOut = (funcInfo.outValue & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0; 1243 bool isFloatOut = !isBoolOut && !isIntOut; 1244 1245 if (!innerGroup || (string(innerGroup->getName()) != funcInfo.caseName)) 1246 { 1247 string groupDesc = string("Built-in function ") + shaderFuncName + "() tests."; 1248 innerGroup = new TestCaseGroup(m_context, funcInfo.caseName, groupDesc.c_str()); 1249 outerGroup->addChild(innerGroup); 1250 } 1251 1252 for (int inScalarSize = 1; inScalarSize <= 4; inScalarSize++) 1253 { 1254 int outScalarSize = ((funcInfo.outValue == VALUE_FLOAT) || (funcInfo.outValue == VALUE_BOOL)) ? 1 : inScalarSize; // \todo [petri] Int. 1255 DataType outDataType = isFloatOut ? s_floatTypes[outScalarSize - 1] 1256 : isIntOut ? s_intTypes[outScalarSize - 1] 1257 : isBoolOut ? s_boolTypes[outScalarSize - 1] 1258 : TYPE_LAST; 1259 1260 ShaderEvalFunc evalFunc = DE_NULL; 1261 if (inScalarSize == 1) evalFunc = funcInfo.evalFuncScalar; 1262 else if (inScalarSize == 2) evalFunc = funcInfo.evalFuncVec2; 1263 else if (inScalarSize == 3) evalFunc = funcInfo.evalFuncVec3; 1264 else if (inScalarSize == 4) evalFunc = funcInfo.evalFuncVec4; 1265 else DE_ASSERT(false); 1266 1267 // Skip if no valid eval func. 1268 // \todo [petri] Better check for V3 only etc. cases? 1269 if (evalFunc == DE_NULL) 1270 continue; 1271 1272 for (int precision = 0; precision < PRECISION_LAST; precision++) 1273 { 1274 if ((funcInfo.precisionMask & (1<<precision)) || 1275 (funcInfo.precisionMask == PRECMASK_NA && precision == PRECISION_MEDIUMP)) // use mediump interpolators for booleans 1276 { 1277 const char* precisionStr = getPrecisionName((Precision)precision); 1278 string precisionPrefix = isBoolCase ? "" : (string(precisionStr) + "_"); 1279 1280 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++) 1281 { 1282 ShaderType shaderType = s_shaderTypes[shaderTypeNdx]; 1283 ShaderDataSpec shaderSpec; 1284 const char* shaderTypeName = getShaderTypeName(shaderType); 1285 bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX; 1286 bool isUnaryOp = (funcInfo.input1.valueType == VALUE_NONE); 1287 1288 // \note Data type names will be added to description and name in a following loop. 1289 string desc = string("Built-in function ") + shaderFuncName + "("; 1290 string name = precisionPrefix; 1291 1292 // Generate shader op. 1293 string shaderOp = string("res = "); 1294 1295 // Setup shader data info. 1296 shaderSpec.numInputs = 0; 1297 shaderSpec.precision = isBoolCase ? PRECISION_LAST : (Precision)precision; 1298 shaderSpec.output = outDataType; 1299 shaderSpec.resultScale = funcInfo.resultScale; 1300 shaderSpec.resultBias = funcInfo.resultBias; 1301 1302 if (funcInfo.type == OPERATOR) 1303 { 1304 if (isUnaryOp && funcInfo.isUnaryPrefix) 1305 shaderOp += shaderFuncName; 1306 } 1307 else if (funcInfo.type == FUNCTION) 1308 shaderOp += string(shaderFuncName) + "("; 1309 else // SIDE_EFFECT_OPERATOR 1310 shaderOp += "in0;\n\t"; 1311 1312 for (int inputNdx = 0; inputNdx < MAX_INPUTS; inputNdx++) 1313 { 1314 const Value& v = (inputNdx == 0) ? funcInfo.input0 : (inputNdx == 1) ? funcInfo.input1 : funcInfo.input2; 1315 const Value& prevV = (inputNdx == 1) ? funcInfo.input0 : (inputNdx == 2) ? funcInfo.input1 : funcInfo.input2; 1316 1317 if (v.valueType == VALUE_NONE) 1318 continue; // Skip unused input. 1319 1320 int curInScalarSize = isScalarType(v.valueType) ? 1 : inScalarSize; 1321 DataType curInDataType = isFloatCase ? s_floatTypes[curInScalarSize - 1] 1322 : isIntCase ? s_intTypes[curInScalarSize - 1] 1323 : isBoolCase ? s_boolTypes[curInScalarSize - 1] 1324 : TYPE_LAST; 1325 1326 // Write input type(s) to case description and name. 1327 1328 if (inputNdx > 0) 1329 desc += ", "; 1330 1331 desc += getDataTypeName(curInDataType); 1332 1333 if (inputNdx == 0 || isScalarType(prevV.valueType) != isScalarType(v.valueType)) // \note Only write input type to case name if different from previous input type (avoid overly long names). 1334 name += string("") + getDataTypeName(curInDataType) + "_"; 1335 1336 // Generate op input source. 1337 1338 if (funcInfo.type == OPERATOR || funcInfo.type == FUNCTION) 1339 { 1340 if (inputNdx != 0) 1341 { 1342 if (funcInfo.type == OPERATOR && !isUnaryOp) 1343 shaderOp += " " + string(shaderFuncName) + " "; 1344 else 1345 shaderOp += ", "; 1346 } 1347 1348 shaderOp += "in" + de::toString(inputNdx); 1349 1350 if (funcInfo.type == OPERATOR && isUnaryOp && !funcInfo.isUnaryPrefix) 1351 shaderOp += string(shaderFuncName); 1352 } 1353 else 1354 { 1355 DE_ASSERT(funcInfo.type == SIDE_EFFECT_OPERATOR); 1356 1357 if (inputNdx != 0 || (isUnaryOp && funcInfo.isUnaryPrefix)) 1358 shaderOp += string("") + (isUnaryOp ? "" : " ") + shaderFuncName + (isUnaryOp ? "" : " "); 1359 1360 shaderOp += inputNdx == 0 ? "res" : "in" + de::toString(inputNdx); // \note in0 has already been assigned to res, so start from in1. 1361 1362 if (isUnaryOp && !funcInfo.isUnaryPrefix) 1363 shaderOp += shaderFuncName; 1364 } 1365 1366 // Fill in shader info. 1367 shaderSpec.inputs[shaderSpec.numInputs++] = ShaderValue(curInDataType, v.rangeMin, v.rangeMax); 1368 } 1369 1370 if (funcInfo.type == FUNCTION) 1371 shaderOp += ")"; 1372 1373 shaderOp += ";"; 1374 1375 desc += ")."; 1376 name += shaderTypeName; 1377 1378 // Create the test case. 1379 innerGroup->addChild(new ShaderOperatorCase(m_context, name.c_str(), desc.c_str(), isVertexCase, evalFunc, shaderOp.c_str(), shaderSpec)); 1380 } 1381 } 1382 } 1383 } 1384 } 1385 } 1386 1387 // The ?: selection operator. 1388 1389 static const struct 1390 { 1391 DataType type; // The type of "Y" and "Z" operands in "X ? Y : Z" (X is always bool). 1392 ShaderEvalFunc evalFunc; 1393 } s_selectionInfo[] = 1394 { 1395 { TYPE_FLOAT, eval_selection_float }, 1396 { TYPE_FLOAT_VEC2, eval_selection_vec2 }, 1397 { TYPE_FLOAT_VEC3, eval_selection_vec3 }, 1398 { TYPE_FLOAT_VEC4, eval_selection_vec4 }, 1399 { TYPE_INT, eval_selection_int }, 1400 { TYPE_INT_VEC2, eval_selection_ivec2 }, 1401 { TYPE_INT_VEC3, eval_selection_ivec3 }, 1402 { TYPE_INT_VEC4, eval_selection_ivec4 }, 1403 { TYPE_BOOL, eval_selection_bool }, 1404 { TYPE_BOOL_VEC2, eval_selection_bvec2 }, 1405 { TYPE_BOOL_VEC3, eval_selection_bvec3 }, 1406 { TYPE_BOOL_VEC4, eval_selection_bvec4 } 1407 }; 1408 1409 TestCaseGroup* selectionGroup = new TestCaseGroup(m_context, "selection", "Selection operator tests"); 1410 addChild(selectionGroup); 1411 1412 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_selectionInfo); typeNdx++) 1413 { 1414 DataType curType = s_selectionInfo[typeNdx].type; 1415 ShaderEvalFunc evalFunc = s_selectionInfo[typeNdx].evalFunc; 1416 bool isBoolCase = isDataTypeBoolOrBVec(curType); 1417 bool isFloatCase = isDataTypeFloatOrVec(curType); 1418 bool isIntCase = isDataTypeIntOrIVec(curType); 1419 const char* dataTypeStr = getDataTypeName(curType); 1420 1421 DE_ASSERT(isBoolCase || isFloatCase || isIntCase); 1422 DE_UNREF(isIntCase); 1423 1424 for (int precision = 0; precision < (int)PRECISION_LAST; precision++) 1425 { 1426 if (isBoolCase && precision != PRECISION_MEDIUMP) // Use mediump interpolators for booleans. 1427 continue; 1428 1429 const char* precisionStr = getPrecisionName((Precision)precision); 1430 string precisionPrefix = isBoolCase ? "" : (string(precisionStr) + "_"); 1431 1432 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++) 1433 { 1434 ShaderType shaderType = s_shaderTypes[shaderTypeNdx]; 1435 ShaderDataSpec shaderSpec; 1436 const char* shaderTypeName = getShaderTypeName(shaderType); 1437 bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX; 1438 1439 string name = precisionPrefix + dataTypeStr + "_" + shaderTypeName; 1440 1441 shaderSpec.numInputs = 3; 1442 shaderSpec.precision = isBoolCase ? PRECISION_LAST : (Precision)precision; 1443 shaderSpec.output = curType; 1444 shaderSpec.resultScale = isBoolCase ? 1.0f : isFloatCase ? 0.5f : 0.1f; 1445 shaderSpec.resultBias = isBoolCase ? 0.0f : isFloatCase ? 0.5f : 0.5f; 1446 1447 float rangeMin = isBoolCase ? -1.0f : isFloatCase ? -1.0f : -5.0f; 1448 float rangeMax = isBoolCase ? 1.0f : isFloatCase ? 1.0f : 5.0f; 1449 1450 shaderSpec.inputs[0] = ShaderValue(TYPE_BOOL, -1.0f, 1.0f); 1451 shaderSpec.inputs[1] = ShaderValue(curType, rangeMin, rangeMax); 1452 shaderSpec.inputs[2] = ShaderValue(curType, rangeMin, rangeMax); 1453 1454 selectionGroup->addChild(new ShaderOperatorCase(m_context, name.c_str(), "", isVertexCase, evalFunc, "res = in0 ? in1 : in2;", shaderSpec)); 1455 } 1456 } 1457 } 1458 1459 // The sequence operator (comma). 1460 1461 TestCaseGroup* sequenceGroup = new TestCaseGroup(m_context, "sequence", "Sequence operator tests"); 1462 addChild(sequenceGroup); 1463 1464 TestCaseGroup* sequenceNoSideEffGroup = new TestCaseGroup(m_context, "no_side_effects", "Sequence tests without side-effects"); 1465 TestCaseGroup* sequenceSideEffGroup = new TestCaseGroup(m_context, "side_effects", "Sequence tests with side-effects"); 1466 sequenceGroup->addChild(sequenceNoSideEffGroup); 1467 sequenceGroup->addChild(sequenceSideEffGroup); 1468 1469 static const struct 1470 { 1471 bool containsSideEffects; 1472 const char* caseName; 1473 const char* expressionStr; 1474 int numInputs; 1475 DataType inputTypes[MAX_INPUTS]; 1476 DataType resultType; 1477 ShaderEvalFunc evalFunc; 1478 } s_sequenceCases[] = 1479 { 1480 { false, "vec4", "in0, in2 + in1, in1 + in0", 3, { TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4 }, TYPE_FLOAT_VEC4, evalSequenceNoSideEffCase0 }, 1481 { false, "float_int", "in0 + in2, in1 + in1", 3, { TYPE_FLOAT, TYPE_INT, TYPE_FLOAT }, TYPE_INT, evalSequenceNoSideEffCase1 }, 1482 { false, "bool_vec2", "in0 && in1, in0, ivec2(vec2(in0) + in2)", 3, { TYPE_BOOL, TYPE_BOOL, TYPE_FLOAT_VEC2 }, TYPE_INT_VEC2, evalSequenceNoSideEffCase2 }, 1483 { false, "vec4_ivec4_bvec4", "in0 + vec4(in1), in2, in1", 3, { TYPE_FLOAT_VEC4, TYPE_INT_VEC4, TYPE_BOOL_VEC4 }, TYPE_INT_VEC4, evalSequenceNoSideEffCase3 }, 1484 1485 { true, "vec4", "in0++, in1 = in0 + in2, in2 = in1", 3, { TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4, TYPE_FLOAT_VEC4 }, TYPE_FLOAT_VEC4, evalSequenceSideEffCase0 }, 1486 { true, "float_int", "in1++, in0 = float(in1), in1 = int(in0 + in2)", 3, { TYPE_FLOAT, TYPE_INT, TYPE_FLOAT }, TYPE_INT, evalSequenceSideEffCase1 }, 1487 { true, "bool_vec2", "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)", 3, { TYPE_BOOL, TYPE_BOOL, TYPE_FLOAT_VEC2 }, TYPE_INT_VEC2, evalSequenceSideEffCase2 }, 1488 { 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 } 1489 }; 1490 1491 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_sequenceCases); caseNdx++) 1492 { 1493 for (int precision = 0; precision < (int)PRECISION_LAST; precision++) 1494 { 1495 for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++) 1496 { 1497 ShaderType shaderType = s_shaderTypes[shaderTypeNdx]; 1498 ShaderDataSpec shaderSpec; 1499 const char* shaderTypeName = getShaderTypeName(shaderType); 1500 bool isVertexCase = (ShaderType)shaderType == SHADERTYPE_VERTEX; 1501 1502 string name = string("") + getPrecisionName((Precision)precision) + "_" + s_sequenceCases[caseNdx].caseName + "_" + shaderTypeName; 1503 1504 shaderSpec.numInputs = s_sequenceCases[caseNdx].numInputs; 1505 shaderSpec.precision = (Precision)precision; 1506 shaderSpec.output = s_sequenceCases[caseNdx].resultType; 1507 shaderSpec.resultScale = 0.5f; 1508 shaderSpec.resultBias = 0.0f; 1509 1510 for (int inputNdx = 0; inputNdx < s_sequenceCases[caseNdx].numInputs; inputNdx++) 1511 { 1512 DataType type = s_sequenceCases[caseNdx].inputTypes[inputNdx]; 1513 float rangeMin = isDataTypeFloatOrVec(type) ? -0.5f : isDataTypeIntOrIVec(type) ? -2.0f : -1.0f; 1514 float rangeMax = isDataTypeFloatOrVec(type) ? 0.5f : isDataTypeIntOrIVec(type) ? 2.0f : 1.0f; 1515 1516 shaderSpec.inputs[inputNdx] = ShaderValue(type, rangeMin, rangeMax); 1517 } 1518 1519 string expression = string("") + "res = (" + s_sequenceCases[caseNdx].expressionStr + ");"; 1520 1521 TestCaseGroup* group = s_sequenceCases[caseNdx].containsSideEffects ? sequenceSideEffGroup : sequenceNoSideEffGroup; 1522 group->addChild(new ShaderOperatorCase(m_context, name.c_str(), "", isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression.c_str(), shaderSpec)); 1523 } 1524 } 1525 } 1526 } 1527 1528 } // Functional 1529 } // gles2 1530 } // deqp 1531