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 39using namespace tcu; 40using namespace glu; 41using namespace deqp::gls; 42 43using std::map; 44using std::pair; 45using std::vector; 46using std::string; 47using std::ostringstream; 48 49namespace deqp 50{ 51namespace gles3 52{ 53namespace Functional 54{ 55 56#if defined(abs) 57# undef abs 58#endif 59 60using de::min; 61using de::max; 62using de::clamp; 63 64// \note VS2013 gets confused without these 65using tcu::asinh; 66using tcu::acosh; 67using tcu::atanh; 68using tcu::exp2; 69using tcu::log2; 70using tcu::trunc; 71 72inline float abs (float v) { return deFloatAbs(v); } 73 74inline bool logicalAnd (bool a, bool b) { return (a && b); } 75inline bool logicalOr (bool a, bool b) { return (a || b); } 76inline bool logicalXor (bool a, bool b) { return (a != b); } 77 78// \note stdlib.h defines div() that is not compatible with the macros. 79template<typename T> inline T div (T a, T b) { return a / b; } 80 81template<typename T> inline T leftShift (T value, int amount) { return value << amount; } 82 83inline deUint32 rightShift (deUint32 value, int amount) { return value >> amount; } 84inline int rightShift (int value, int amount) { return (value >> amount) | (value >= 0 ? 0 : ~(~0U >> amount)); } // \note Arithmetic shift. 85 86template<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 94template<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 102template<typename T, int Size> Vector<T, Size> leftShiftVecScalar (const Vector<T, Size>& value, int amount) { return leftShift(value, Vector<int, Size>(amount)); } 103template<typename T, int Size> Vector<T, Size> rightShiftVecScalar (const Vector<T, Size>& value, int amount) { return rightShift(value, Vector<int, Size>(amount)); } 104 105template<typename T, int Size> 106inline 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 114template<typename T, int Size> 115inline 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 123template<typename T, int Size> 124inline 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 132template<typename T, int Size> 133inline 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 141template<typename T, int Size> 142inline 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 150template<typename T, int Size> 151inline 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 159inline float addOne (float v) { return v + 1.0f; } 160inline float subOne (float v) { return v - 1.0f; } 161inline int addOne (int v) { return v + 1; } 162inline int subOne (int v) { return v - 1; } 163inline deUint32 addOne (deUint32 v) { return v + 1; } 164inline deUint32 subOne (deUint32 v) { return v - 1; } 165 166template<int Size> inline Vector<float, Size> addOne (const Vector<float, Size>& v) { return v + 1.0f; } 167template<int Size> inline Vector<float, Size> subOne (const Vector<float, Size>& v) { return v - 1.0f; } 168template<int Size> inline Vector<int, Size> addOne (const Vector<int, Size>& v) { return v + 1; } 169template<int Size> inline Vector<int, Size> subOne (const Vector<int, Size>& v) { return v - 1; } 170template<int Size> inline Vector<deUint32, Size> addOne (const Vector<deUint32, Size>& v) { return v + 1U; } 171template<int Size> inline Vector<deUint32, Size> subOne (const Vector<deUint32, Size>& v) { return (v.asInt() - 1).asUint(); } 172 173template<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. 178template<int Size> inline Vector<deUint32, Size> subVecScalar (const Vector<deUint32, Size>& v, deUint32 s) { return (v.asInt() - (int)s).asUint(); } 179 180template<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. 183inline int add (int a, int b) { return static_cast<int>(static_cast<deInt64>(a) + static_cast<deInt64>(b)); } 184inline int sub (int a, int b) { return static_cast<int>(static_cast<deInt64>(a) - static_cast<deInt64>(b)); } 185inline int mul (int a, int b) { return static_cast<int>(static_cast<deInt64>(a) * static_cast<deInt64>(b)); } 186 187inline deUint32 add (deUint32 a, deUint32 b) { return a + b; } 188inline deUint32 sub (deUint32 a, deUint32 b) { return a - b; } 189inline deUint32 mul (deUint32 a, deUint32 b) { return a * b; } 190 191#define DECLARE_IVEC_BINARY_FUNC(OP_NAME) \ 192template <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) \ 201template<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) \ 210template<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 218DECLARE_IVEC_BINARY_FUNC(add) 219DECLARE_IVEC_BINARY_FUNC(sub) 220DECLARE_IVEC_BINARY_FUNC(mul) 221DECLARE_IVEC_INT_BINARY_FUNC(add) 222DECLARE_IVEC_INT_BINARY_FUNC(sub) 223DECLARE_IVEC_INT_BINARY_FUNC(mul) 224DECLARE_INT_IVEC_BINARY_FUNC(add) 225DECLARE_INT_IVEC_BINARY_FUNC(sub) 226DECLARE_INT_IVEC_BINARY_FUNC(mul) 227 228template<typename T, int Size> inline Vector<T, Size> subVecScalar (const Vector<T, Size>& v, T s) { return v - s; } 229template<typename T, int Size> inline Vector<T, Size> mulVecScalar (const Vector<T, Size>& v, T s) { return v * s; } 230template<typename T, int Size> inline Vector<T, Size> divVecScalar (const Vector<T, Size>& v, T s) { return v / s; } 231template<typename T, int Size> inline Vector<T, Size> modVecScalar (const Vector<T, Size>& v, T s) { return mod(v, Vector<T, Size>(s)); } 232template<typename T, int Size> inline Vector<T, Size> bitwiseAndVecScalar (const Vector<T, Size>& v, T s) { return bitwiseAnd(v, Vector<T, Size>(s)); } 233template<typename T, int Size> inline Vector<T, Size> bitwiseOrVecScalar (const Vector<T, Size>& v, T s) { return bitwiseOr(v, Vector<T, Size>(s)); } 234template<typename T, int Size> inline Vector<T, Size> bitwiseXorVecScalar (const Vector<T, Size>& v, T s) { return bitwiseXor(v, Vector<T, Size>(s)); } 235 236template<typename T, int Size> inline Vector<T, Size> addScalarVec (T s, const Vector<T, Size>& v) { return s + v; } 237template<typename T, int Size> inline Vector<T, Size> subScalarVec (T s, const Vector<T, Size>& v) { return s - v; } 238template<typename T, int Size> inline Vector<T, Size> mulScalarVec (T s, const Vector<T, Size>& v) { return s * v; } 239template<typename T, int Size> inline Vector<T, Size> divScalarVec (T s, const Vector<T, Size>& v) { return s / v; } 240template<typename T, int Size> inline Vector<T, Size> modScalarVec (T s, const Vector<T, Size>& v) { return mod(Vector<T, Size>(s), v); } 241template<typename T, int Size> inline Vector<T, Size> bitwiseAndScalarVec (T s, const Vector<T, Size>& v) { return bitwiseAnd(Vector<T, Size>(s), v); } 242template<typename T, int Size> inline Vector<T, Size> bitwiseOrScalarVec (T s, const Vector<T, Size>& v) { return bitwiseOr(Vector<T, Size>(s), v); } 243template<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" 248inline 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" 250inline 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)" 252inline 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" 254inline 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" 256inline 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)" 258inline 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)" 260inline 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++" 262inline 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. 265void 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)); } 266void evalSequenceNoSideEffCase1 (ShaderEvalContext& ctx) { ctx.color.x() = (float)sequenceNoSideEffCase1 (ctx.in[0].z(), (deUint32)ctx.in[1].x(), ctx.in[2].y()); } 267void 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(); } 268void 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(); } 269void 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)); } 270void evalSequenceSideEffCase1 (ShaderEvalContext& ctx) { ctx.color.x() = (float)sequenceSideEffCase1 (ctx.in[0].z(), (deUint32)ctx.in[1].x(), ctx.in[2].y()); } 271void 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(); } 272void 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 274static 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 282static 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 292static 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 301enum 302{ 303 MAX_INPUTS = 3 304}; 305 306enum 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 318enum 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 353static inline bool isScalarType (ValueType type) 354{ 355 return type == VALUE_FLOAT || type == VALUE_BOOL || type == VALUE_INT || type == VALUE_UINT; 356} 357 358static inline bool isFloatType (ValueType type) 359{ 360 return (type & (VALUE_FLOAT | VALUE_FLOAT_VEC | VALUE_FLOAT_GENTYPE)) != 0; 361} 362 363static inline bool isIntType (ValueType type) 364{ 365 return (type & (VALUE_INT | VALUE_INT_VEC | VALUE_INT_GENTYPE)) != 0; 366} 367 368static inline bool isUintType (ValueType type) 369{ 370 return (type & (VALUE_UINT | VALUE_UINT_VEC | VALUE_UINT_GENTYPE)) != 0; 371} 372 373static inline bool isBoolType (ValueType type) 374{ 375 return (type & (VALUE_BOOL | VALUE_BOOL_VEC | VALUE_BOOL_GENTYPE)) != 0; 376} 377 378static 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 414static 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. 425class FloatScalar 426{ 427public: 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 442 FloatScalar (float c) : m_isConstant(true), m_value(c) {} 443 FloatScalar (Symbol s) : m_isConstant(false), m_value(s) {} 444 445 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 469 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 499private: 500 bool m_isConstant; 501 502 union ConstantOrSymbol 503 { 504 float constant; 505 Symbol symbol; 506 507 ConstantOrSymbol (float c) : constant (c) {} 508 ConstantOrSymbol (Symbol s) : symbol (s) {} 509 } m_value; 510}; 511 512struct Value 513{ 514 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 526enum 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 533struct BuiltinFuncInfo 534{ 535 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 561 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 606static 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 611static 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. 617static 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 622static 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. 628static 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 635struct BuiltinFuncGroup 636{ 637 BuiltinFuncGroup (const char* name_, const char* description_) : name(name_), description(description_) {} 638 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 645static 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 652static const char* s_outSwizzles[] = { "x", "yz", "xyz", "xyzw" }; 653 654static 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 664class OperatorShaderEvaluator : public ShaderEvaluator 665{ 666public: 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 681 virtual ~OperatorShaderEvaluator (void) 682 { 683 } 684 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 701private: 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 716struct ShaderValue 717{ 718 ShaderValue (DataType type_, const FloatScalar& rangeMin_, const FloatScalar& rangeMax_) 719 : type (type_) 720 , rangeMin (rangeMin_) 721 , rangeMax (rangeMax_) 722 { 723 } 724 725 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 737struct ShaderDataSpec 738{ 739 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 762class ShaderOperatorCase : public ShaderRenderCase 763{ 764public: 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 768protected: 769 void setupShaderData (void); 770 771private: 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 780ShaderOperatorCase::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 788void 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 1092ShaderOperatorCase::~ShaderOperatorCase (void) 1093{ 1094} 1095 1096// ShaderOperatorTests. 1097 1098ShaderOperatorTests::ShaderOperatorTests(Context& context) 1099 : TestCaseGroup(context, "operator", "Operator tests.") 1100{ 1101} 1102 1103ShaderOperatorTests::~ShaderOperatorTests (void) 1104{ 1105} 1106 1107// Vector math functions. 1108template<typename T> inline T nop (T f) { return f; } 1109 1110template <typename T, int Size> 1111Vector<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 1273DECLARE_UNARY_GENTYPE_FUNCS(nop) 1274DECLARE_UNARY_GENTYPE_FUNCS(negate) 1275DECLARE_UNARY_GENTYPE_FUNCS(addOne) 1276DECLARE_UNARY_GENTYPE_FUNCS(subOne) 1277DECLARE_BINARY_GENTYPE_FUNCS(add) 1278DECLARE_BINARY_GENTYPE_FUNCS(sub) 1279DECLARE_BINARY_GENTYPE_FUNCS(mul) 1280DECLARE_BINARY_GENTYPE_FUNCS(div) 1281 1282void eval_selection_float (ShaderEvalContext& c) { c.color.x() = selection(c.in[0].z() > 0.0f, c.in[1].x(), c.in[2].y()); } 1283void 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)); } 1284void 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)); } 1285void 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 1287DECLARE_UNARY_INT_GENTYPE_FUNCS(nop) 1288DECLARE_UNARY_INT_GENTYPE_FUNCS(negate) 1289DECLARE_UNARY_INT_GENTYPE_FUNCS(addOne) 1290DECLARE_UNARY_INT_GENTYPE_FUNCS(subOne) 1291DECLARE_UNARY_INT_GENTYPE_FUNCS(bitwiseNot) 1292DECLARE_BINARY_INT_GENTYPE_FUNCS(add) 1293DECLARE_BINARY_INT_GENTYPE_FUNCS(sub) 1294DECLARE_BINARY_INT_GENTYPE_FUNCS(mul) 1295DECLARE_BINARY_INT_GENTYPE_FUNCS(div) 1296DECLARE_BINARY_INT_GENTYPE_FUNCS(mod) 1297DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseAnd) 1298DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseOr) 1299DECLARE_BINARY_INT_GENTYPE_FUNCS(bitwiseXor) 1300 1301void eval_leftShift_int (ShaderEvalContext& c) { c.color.x() = (float)leftShift((int)c.in[0].z(), (int)c.in[1].x()); } 1302DECLARE_BINARY_INT_VEC_FUNCS(leftShift) 1303void eval_rightShift_int (ShaderEvalContext& c) { c.color.x() = (float)rightShift((int)c.in[0].z(), (int)c.in[1].x()); } 1304DECLARE_BINARY_INT_VEC_FUNCS(rightShift) 1305DECLARE_IVEC_INT_FUNCS(leftShiftVecScalar) 1306DECLARE_IVEC_INT_FUNCS(rightShiftVecScalar) 1307 1308void 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()); } 1309void 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(); } 1310void 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(); } 1311void 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 1313DECLARE_UNARY_UINT_GENTYPE_FUNCS(nop) 1314DECLARE_UNARY_UINT_GENTYPE_FUNCS(negate) 1315DECLARE_UNARY_UINT_GENTYPE_FUNCS(bitwiseNot) 1316DECLARE_UNARY_UINT_GENTYPE_FUNCS(addOne) 1317DECLARE_UNARY_UINT_GENTYPE_FUNCS(subOne) 1318DECLARE_BINARY_UINT_GENTYPE_FUNCS(add) 1319DECLARE_BINARY_UINT_GENTYPE_FUNCS(sub) 1320DECLARE_BINARY_UINT_GENTYPE_FUNCS(mul) 1321DECLARE_BINARY_UINT_GENTYPE_FUNCS(div) 1322DECLARE_BINARY_UINT_GENTYPE_FUNCS(mod) 1323DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseAnd) 1324DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseOr) 1325DECLARE_BINARY_UINT_GENTYPE_FUNCS(bitwiseXor) 1326 1327DECLARE_UINT_INT_GENTYPE_FUNCS(leftShift) 1328DECLARE_UINT_INT_GENTYPE_FUNCS(rightShift) 1329DECLARE_UVEC_INT_FUNCS(leftShiftVecScalar) 1330DECLARE_UVEC_INT_FUNCS(rightShiftVecScalar) 1331 1332void 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()); } 1333void 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(); } 1334void 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(); } 1335void 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 1337DECLARE_UNARY_BOOL_GENTYPE_FUNCS(boolNot) 1338DECLARE_BINARY_BOOL_FUNCS(logicalAnd) 1339DECLARE_BINARY_BOOL_FUNCS(logicalOr) 1340DECLARE_BINARY_BOOL_FUNCS(logicalXor) 1341 1342void 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); } 1343void 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(); } 1344void 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(); } 1345void 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 1347DECLARE_VEC_FLOAT_FUNCS(addVecScalar) 1348DECLARE_VEC_FLOAT_FUNCS(subVecScalar) 1349DECLARE_VEC_FLOAT_FUNCS(mulVecScalar) 1350DECLARE_VEC_FLOAT_FUNCS(divVecScalar) 1351 1352DECLARE_FLOAT_VEC_FUNCS(addScalarVec) 1353DECLARE_FLOAT_VEC_FUNCS(subScalarVec) 1354DECLARE_FLOAT_VEC_FUNCS(mulScalarVec) 1355DECLARE_FLOAT_VEC_FUNCS(divScalarVec) 1356 1357DECLARE_IVEC_INT_FUNCS(addVecScalar) 1358DECLARE_IVEC_INT_FUNCS(subVecScalar) 1359DECLARE_IVEC_INT_FUNCS(mulVecScalar) 1360DECLARE_IVEC_INT_FUNCS(divVecScalar) 1361DECLARE_IVEC_INT_FUNCS(modVecScalar) 1362DECLARE_IVEC_INT_FUNCS(bitwiseAndVecScalar) 1363DECLARE_IVEC_INT_FUNCS(bitwiseOrVecScalar) 1364DECLARE_IVEC_INT_FUNCS(bitwiseXorVecScalar) 1365 1366DECLARE_INT_IVEC_FUNCS(addScalarVec) 1367DECLARE_INT_IVEC_FUNCS(subScalarVec) 1368DECLARE_INT_IVEC_FUNCS(mulScalarVec) 1369DECLARE_INT_IVEC_FUNCS(divScalarVec) 1370DECLARE_INT_IVEC_FUNCS(modScalarVec) 1371DECLARE_INT_IVEC_FUNCS(bitwiseAndScalarVec) 1372DECLARE_INT_IVEC_FUNCS(bitwiseOrScalarVec) 1373DECLARE_INT_IVEC_FUNCS(bitwiseXorScalarVec) 1374 1375DECLARE_UVEC_UINT_FUNCS(addVecScalar) 1376DECLARE_UVEC_UINT_FUNCS(subVecScalar) 1377DECLARE_UVEC_UINT_FUNCS(mulVecScalar) 1378DECLARE_UVEC_UINT_FUNCS(divVecScalar) 1379DECLARE_UVEC_UINT_FUNCS(modVecScalar) 1380DECLARE_UVEC_UINT_FUNCS(bitwiseAndVecScalar) 1381DECLARE_UVEC_UINT_FUNCS(bitwiseOrVecScalar) 1382DECLARE_UVEC_UINT_FUNCS(bitwiseXorVecScalar) 1383 1384DECLARE_UINT_UVEC_FUNCS(addScalarVec) 1385DECLARE_UINT_UVEC_FUNCS(subScalarVec) 1386DECLARE_UINT_UVEC_FUNCS(mulScalarVec) 1387DECLARE_UINT_UVEC_FUNCS(divScalarVec) 1388DECLARE_UINT_UVEC_FUNCS(modScalarVec) 1389DECLARE_UINT_UVEC_FUNCS(bitwiseAndScalarVec) 1390DECLARE_UINT_UVEC_FUNCS(bitwiseOrScalarVec) 1391DECLARE_UINT_UVEC_FUNCS(bitwiseXorScalarVec) 1392 1393// Built-in functions. 1394 1395DECLARE_UNARY_GENTYPE_FUNCS(radians) 1396DECLARE_UNARY_GENTYPE_FUNCS(degrees) 1397DECLARE_UNARY_GENTYPE_FUNCS(sin) 1398DECLARE_UNARY_GENTYPE_FUNCS(cos) 1399DECLARE_UNARY_GENTYPE_FUNCS(tan) 1400DECLARE_UNARY_GENTYPE_FUNCS(asin) 1401DECLARE_UNARY_GENTYPE_FUNCS(acos) 1402DECLARE_UNARY_GENTYPE_FUNCS(atan) 1403DECLARE_BINARY_GENTYPE_FUNCS(atan2) 1404DECLARE_UNARY_GENTYPE_FUNCS(sinh) 1405DECLARE_UNARY_GENTYPE_FUNCS(cosh) 1406DECLARE_UNARY_GENTYPE_FUNCS(tanh) 1407DECLARE_UNARY_GENTYPE_FUNCS(asinh) 1408DECLARE_UNARY_GENTYPE_FUNCS(acosh) 1409DECLARE_UNARY_GENTYPE_FUNCS(atanh) 1410 1411DECLARE_BINARY_GENTYPE_FUNCS(pow) 1412DECLARE_UNARY_GENTYPE_FUNCS(exp) 1413DECLARE_UNARY_GENTYPE_FUNCS(log) 1414DECLARE_UNARY_GENTYPE_FUNCS(exp2) 1415DECLARE_UNARY_GENTYPE_FUNCS(log2) 1416DECLARE_UNARY_GENTYPE_FUNCS(sqrt) 1417DECLARE_UNARY_GENTYPE_FUNCS(inverseSqrt) 1418 1419DECLARE_UNARY_GENTYPE_FUNCS(abs) 1420DECLARE_UNARY_GENTYPE_FUNCS(sign) 1421DECLARE_UNARY_GENTYPE_FUNCS(floor) 1422DECLARE_UNARY_GENTYPE_FUNCS(trunc) 1423DECLARE_UNARY_GENTYPE_FUNCS(roundToEven) 1424DECLARE_UNARY_GENTYPE_FUNCS(ceil) 1425DECLARE_UNARY_GENTYPE_FUNCS(fract) 1426DECLARE_BINARY_GENTYPE_FUNCS(mod) 1427DECLARE_VEC_FLOAT_FUNCS(modVecScalar) 1428DECLARE_BINARY_GENTYPE_FUNCS(min) 1429DECLARE_VEC_FLOAT_FUNCS(minVecScalar) 1430DECLARE_BINARY_INT_GENTYPE_FUNCS(min) 1431DECLARE_IVEC_INT_FUNCS(minVecScalar) 1432DECLARE_BINARY_UINT_GENTYPE_FUNCS(min) 1433DECLARE_UVEC_UINT_FUNCS(minVecScalar) 1434DECLARE_BINARY_GENTYPE_FUNCS(max) 1435DECLARE_VEC_FLOAT_FUNCS(maxVecScalar) 1436DECLARE_BINARY_INT_GENTYPE_FUNCS(max) 1437DECLARE_IVEC_INT_FUNCS(maxVecScalar) 1438DECLARE_BINARY_UINT_GENTYPE_FUNCS(max) 1439DECLARE_UVEC_UINT_FUNCS(maxVecScalar) 1440DECLARE_TERNARY_GENTYPE_FUNCS(clamp) 1441DECLARE_VEC_FLOAT_FLOAT_FUNCS(clampVecScalarScalar) 1442DECLARE_TERNARY_INT_GENTYPE_FUNCS(clamp) 1443DECLARE_IVEC_INT_INT_FUNCS(clampVecScalarScalar) 1444DECLARE_TERNARY_UINT_GENTYPE_FUNCS(clamp) 1445DECLARE_UVEC_UINT_UINT_FUNCS(clampVecScalarScalar) 1446DECLARE_TERNARY_GENTYPE_FUNCS(mix) 1447DECLARE_VEC_VEC_FLOAT_FUNCS(mixVecVecScalar) 1448DECLARE_BINARY_GENTYPE_FUNCS(step) 1449DECLARE_FLOAT_VEC_FUNCS(stepScalarVec) 1450DECLARE_TERNARY_GENTYPE_FUNCS(smoothStep) 1451DECLARE_FLOAT_FLOAT_VEC_FUNCS(smoothStepScalarScalarVec) 1452 1453DECLARE_UNARY_SCALAR_GENTYPE_FUNCS(length) 1454DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(distance) 1455DECLARE_BINARY_SCALAR_GENTYPE_FUNCS(dot) 1456void eval_cross_vec3 (ShaderEvalContext& c) { c.color.xyz() = cross(c.in[0].swizzle(2, 0, 1), c.in[1].swizzle(1, 2, 0)); } 1457 1458DECLARE_UNARY_GENTYPE_FUNCS(normalize) 1459DECLARE_TERNARY_GENTYPE_FUNCS(faceForward) 1460DECLARE_BINARY_GENTYPE_FUNCS(reflect) 1461 1462void eval_refract_float (ShaderEvalContext& c) { c.color.x() = refract(c.in[0].z(), c.in[1].x(), c.in[2].y()); } 1463void 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()); } 1464void 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()); } 1465void 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 1517DECLARE_FLOAT_COMPARE_FUNCS(allEqual) 1518DECLARE_FLOAT_COMPARE_FUNCS(anyNotEqual) 1519DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThan) 1520DECLARE_FLOAT_CWISE_COMPARE_FUNCS(lessThanEqual) 1521DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThan) 1522DECLARE_FLOAT_CWISE_COMPARE_FUNCS(greaterThanEqual) 1523DECLARE_FLOAT_CWISE_COMPARE_FUNCS(equal) 1524DECLARE_FLOAT_CWISE_COMPARE_FUNCS(notEqual) 1525 1526DECLARE_INT_COMPARE_FUNCS(allEqual) 1527DECLARE_INT_COMPARE_FUNCS(anyNotEqual) 1528DECLARE_INT_CWISE_COMPARE_FUNCS(lessThan) 1529DECLARE_INT_CWISE_COMPARE_FUNCS(lessThanEqual) 1530DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThan) 1531DECLARE_INT_CWISE_COMPARE_FUNCS(greaterThanEqual) 1532DECLARE_INT_CWISE_COMPARE_FUNCS(equal) 1533DECLARE_INT_CWISE_COMPARE_FUNCS(notEqual) 1534 1535DECLARE_UINT_COMPARE_FUNCS(allEqual) 1536DECLARE_UINT_COMPARE_FUNCS(anyNotEqual) 1537DECLARE_UINT_CWISE_COMPARE_FUNCS(lessThan) 1538DECLARE_UINT_CWISE_COMPARE_FUNCS(lessThanEqual) 1539DECLARE_UINT_CWISE_COMPARE_FUNCS(greaterThan) 1540DECLARE_UINT_CWISE_COMPARE_FUNCS(greaterThanEqual) 1541DECLARE_UINT_CWISE_COMPARE_FUNCS(equal) 1542DECLARE_UINT_CWISE_COMPARE_FUNCS(notEqual) 1543 1544DECLARE_BOOL_COMPARE_FUNCS(allEqual) 1545DECLARE_BOOL_COMPARE_FUNCS(anyNotEqual) 1546DECLARE_BOOL_CWISE_COMPARE_FUNCS(equal) 1547DECLARE_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 1561DECLARE_UNARY_SCALAR_BVEC_FUNCS(any, boolAny) 1562DECLARE_UNARY_SCALAR_BVEC_FUNCS(all, boolAll) 1563 1564void 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