Make random number usage platform independent
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuVectorUtil.hpp
1 #ifndef _TCUVECTORUTIL_HPP
2 #define _TCUVECTORUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Tester Core
5  * ----------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vector utility functions.
24  *//*--------------------------------------------------------------------*/
25
26 #include "tcuDefs.hpp"
27 #include "tcuVector.hpp"
28 #include "deRandom.hpp"
29 #include "deMeta.hpp"
30 #include "deMath.h"
31 #include "deInt32.h"
32
33 #include <ostream>
34 #include <math.h>
35
36 namespace tcu
37 {
38
39 static const float PI = 3.141592653589793238f;
40
41 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_WIN32 && DE_COMPILER == DE_COMPILER_CLANG)
42 inline float abs                        (float f) { return deFloatAbs(f); }
43 #endif
44
45 template<typename T> inline T add                       (T a, T b) { return a + b; }
46 template<typename T> inline T sub                       (T a, T b) { return a - b; }
47 template<typename T> inline T mul                       (T a, T b) { return a * b; }
48 template<typename T> inline T div                       (T a, T b) { return a / b; }
49
50 template<typename T> inline T bitwiseNot        (T a)           { return ~a; }
51 template<typename T> inline T bitwiseAnd        (T a, T b)      { return a & b; }
52 template<typename T> inline T bitwiseOr         (T a, T b)      { return a | b; }
53 template<typename T> inline T bitwiseXor        (T a, T b)      { return a ^ b; }
54
55 template<typename T> inline T logicalNot        (T a)           { return !a; }
56 template<typename T> inline T logicalAnd        (T a, T b)      { return a && b; }
57 template<typename T> inline T logicalOr         (T a, T b)      { return a || b; }
58
59 template<typename T>    inline T                mod             (T a, T b)                      { return a % b; }
60 template<>                              inline float    mod             (float x, float y)      { return x - y * deFloatFloor(x / y); }
61
62 template<typename T>    inline  T                       negate                          (T f)                   { return -f; }
63 template<>                              inline  deUint32        negate<deUint32>        (deUint32 f)    { return (deUint32)-(int)f;     }
64
65 inline float radians            (float f) { return deFloatRadians(f); }
66 inline float degrees            (float f) { return deFloatDegrees(f); }
67 inline float inverseSqrt        (float f) { return deFloatRsq(f); }
68 inline float sign                       (float f) { return (f < 0.0f) ? -1.0f : ((f > 0.0f) ? +1.0f : 0.0f); }
69 inline float fract                      (float f) { return f - deFloatFloor(f); }
70 inline float mix                        (float x, float y, float a) { return x * (1.0f - a) + y * a; }
71 inline float step                       (float edge, float x) { return (x < edge) ? 0.0f : 1.0f; }
72 inline float smoothStep         (float edge0, float edge1, float x)
73 {
74         if (x <= edge0) return 0.0f;
75         if (x >= edge1) return 1.0f;
76         float t = de::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
77         return t * t * (3.0f - 2.0f * t);
78 }
79
80 inline double mix                       (double x, double y, double a) { return x * (1.0 - a) + y * a; }
81 inline double step                      (double edge, double x) { return (x < edge) ? 0.0 : 1.0; }
82
83 inline float length                     (float f) { return deFloatAbs(f); }
84 inline float distance           (float x, float y) { return deFloatAbs(x - y); }
85 inline float dot                        (float x, float y) { return (x * y); }
86
87 inline float normalize          (float f) { return sign(f); }
88 inline float faceForward        (float n, float i, float ref) { return ((ref * i) < 0.0f) ? n : -n; }
89 inline float reflect            (float i, float n) { return i - 2.0f * (n * i) * n; }
90 inline float refract            (float i, float n, float eta)
91 {
92         float cosAngle = (n * i);
93         float k = 1.0f - eta * eta * (1.0f - cosAngle * cosAngle);
94         if (k < 0.0f)
95                 return 0.0f;
96         else
97                 return eta * i - (eta * cosAngle + deFloatSqrt(k)) * n;
98 }
99
100 template<typename T> inline bool        lessThan                        (T a, T b) { return (a < b); }
101 template<typename T> inline bool        lessThanEqual           (T a, T b) { return (a <= b); }
102 template<typename T> inline bool        greaterThan                     (T a, T b) { return (a > b); }
103 template<typename T> inline bool        greaterThanEqual        (T a, T b) { return (a >= b); }
104 template<typename T> inline bool        equal                           (T a, T b) { return (a == b); }
105 template<typename T> inline bool        notEqual                        (T a, T b) { return (a != b); }
106 template<typename T> inline bool        allEqual                        (T a, T b) { return (a == b); }
107 template<typename T> inline bool        anyNotEqual                     (T a, T b) { return (a != b); }
108
109 inline bool boolNot                             (bool a) { return !a; }
110
111 inline int chopToInt                    (float a) { return deChopFloatToInt32(a); }
112
113 inline float roundToEven (float a)
114 {
115         float q = deFloatFrac(a);
116         float r = a-q;
117
118         if (q > 0.5f)
119                 r += 1.0f;
120         else if (q == 0.5 && (((int)r) % 2 != 0))
121                 r += 1.0f;
122
123         return r;
124 }
125
126 template <typename T, int Size>
127 inline T dot (const Vector<T, Size>& a, const Vector<T, Size>& b)
128 {
129         T res = T();
130         for (int i = 0; i < Size; i++)
131                 res += a.m_data[i] * b.m_data[i];
132         return res;
133 }
134
135 template <typename T, int Size>
136 inline T lengthSquared (const Vector<T, Size>& a)
137 {
138         T sqSum = T();
139         for (int i = 0; i < Size; i++)
140                 sqSum += a.m_data[i] * a.m_data[i];
141         return sqSum;
142 }
143
144 template <typename T, int Size>
145 inline typename de::meta::EnableIf<T, de::meta::TypesSame<T, double>::Value>::Type length (const Vector<T, Size>& a)
146 {
147         return ::sqrt(lengthSquared(a));
148 }
149
150 template <typename T, int Size>
151 inline typename de::meta::EnableIf<T, de::meta::TypesSame<T, float>::Value>::Type length (const Vector<T, Size>& a)
152 {
153         return deFloatSqrt(lengthSquared(a));
154 }
155
156 template <typename T, int Size>
157 inline T distance (const Vector<T, Size>& a, const Vector<T, Size>& b)
158 {
159         return length(a - b);
160 }
161
162 template <typename T, int Size>
163 inline Vector<T, Size> cross (const Vector<T, Size>& a, const Vector<T, Size>& b)
164 {
165         DE_STATIC_ASSERT(Size == 3);
166         return Vector<T, Size>(
167                 a.y() * b.z() - b.y() * a.z(),
168                 a.z() * b.x() - b.z() * a.x(),
169                 a.x() * b.y() - b.x() * a.y());
170 }
171
172 template <typename T, int Size>
173 inline Vector<T, Size> normalize (const Vector<T, Size>& a)
174 {
175         T ooLen = T(1) / length(a);
176         Vector<T, Size> res;
177         for (int i = 0; i < Size; i++)
178                 res.m_data[i] = ooLen * a.m_data[i];
179         return res;
180 }
181
182 template <typename T, int Size>
183 inline Vector<T, Size> faceForward (const Vector<T, Size>& n, const Vector<T, Size>& i, const Vector<T, Size>& ref)
184 {
185         return (dot(ref, i) < T(0)) ? n: -n;
186 }
187
188 template <typename T, int Size>
189 inline Vector<T, Size> reflect (const Vector<T, Size>& i, const Vector<T, Size>& n)
190 {
191         return i - T(2) * dot(n, i) * n;
192 }
193
194 template <typename T, int Size>
195 inline Vector<T, Size> refract (const Vector<T, Size>& i, const Vector<T, Size>& n, T eta)
196 {
197         T cosAngle = dot(n, i);
198         T k = T(1) - eta * eta * (T(1) - cosAngle * cosAngle);
199         if (k < T(0))
200                 return Vector<T, Size>(T(0));
201         else
202                 return i * eta - n * T(eta * cosAngle + ::sqrt(k));
203 }
204
205 template <int Size>
206 Vector<float, Size> mix (const Vector<float, Size>& x, const Vector<float, Size>& y, float a)
207 {
208         Vector<float, Size> res;
209         for (int i = 0; i < Size; i++)
210                 res.m_data[i] = deFloatMix(x.m_data[i], y.m_data[i], a);
211         return res;
212 }
213
214 template <int Size>
215 Vector<double, Size> mix (const Vector<double, Size>& x, const Vector<double, Size>& y, double a)
216 {
217         Vector<double, Size> res;
218         for (int i = 0; i < Size; i++)
219                 res.m_data[i] = deMix(x.m_data[i], y.m_data[i], a);
220         return res;
221 }
222
223 // Piece-wise compare operators.
224
225 template <typename T, int Size>
226 inline Vector<bool, Size> equal (const Vector<T, Size>& a, const Vector<T, Size>& b)
227 {
228         Vector<bool, Size> res;
229         for (int i = 0; i < Size; i++)
230                 res.m_data[i] = a.m_data[i] == b.m_data[i];
231         return res;
232 }
233
234 template <typename T, int Size>
235 inline Vector<bool, Size> notEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
236 {
237         Vector<bool, Size> res;
238         for (int i = 0; i < Size; i++)
239                 res.m_data[i] = a.m_data[i] != b.m_data[i];
240         return res;
241 }
242
243 template <typename T, int Size>
244 inline Vector<bool, Size> lessThan (const Vector<T, Size>& a, const Vector<T, Size>& b)
245 {
246         Vector<bool, Size> res;
247         for (int i = 0; i < Size; i++)
248                 res.m_data[i] = a.m_data[i] < b.m_data[i];
249         return res;
250 }
251
252 template <typename T, int Size>
253 inline Vector<bool, Size> lessThanEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
254 {
255         Vector<bool, Size> res;
256         for (int i = 0; i < Size; i++)
257                 res.m_data[i] = a.m_data[i] <= b.m_data[i];
258         return res;
259 }
260
261 template <typename T, int Size>
262 inline Vector<bool, Size> greaterThan (const Vector<T, Size>& a, const Vector<T, Size>& b)
263 {
264         Vector<bool, Size> res;
265         for (int i = 0; i < Size; i++)
266                 res.m_data[i] = a.m_data[i] > b.m_data[i];
267         return res;
268 }
269
270 template <typename T, int Size>
271 inline Vector<bool, Size> greaterThanEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
272 {
273         Vector<bool, Size> res;
274         for (int i = 0; i < Size; i++)
275                 res.m_data[i] = a.m_data[i] >= b.m_data[i];
276         return res;
277 }
278
279 // Equality comparison operators.
280
281 template <typename T, int Size>
282 inline bool allEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
283 {
284         bool res = true;
285         for (int i = 0; i < Size; i++)
286                 res = res && a.m_data[i] == b.m_data[i];
287         return res;
288 }
289
290 template <typename T, int Size>
291 inline bool anyNotEqual (const Vector<T, Size>& a, const Vector<T, Size>& b)
292 {
293         bool res = false;
294         for (int i = 0; i < Size; i++)
295                 res = res || a.m_data[i] != b.m_data[i];
296         return res;
297 }
298
299 // Boolean built-ins.
300
301 template <int Size>
302 inline Vector<bool, Size> boolNot (const Vector<bool, Size>& a)
303 {
304         Vector<bool, Size> res;
305         for (int i = 0; i < Size; i++)
306                 res.m_data[i] = !a.m_data[i];
307         return res;
308 }
309
310 template <int Size>
311 inline bool boolAny (const Vector<bool, Size>& a)
312 {
313         for (int i = 0; i < Size; i++)
314                 if (a.m_data[i] == true)
315                         return true;
316         return false;
317 }
318
319 template <int Size>
320 inline bool boolAll (const Vector<bool, Size>& a)
321 {
322         for (int i = 0; i < Size; i++)
323                 if (a.m_data[i] == false)
324                         return false;
325         return true;
326 }
327
328 template <int Size>
329 Vector<int, Size> chopToInt (const Vector<float, Size>& v)
330 {
331         Vector<int, Size> res;
332         for (int i = 0; i < Size; i++)
333                 res.m_data[i] = chopToInt(v.m_data[i]);
334         return res;
335 }
336
337 // Vector construction using selection based on boolean vector.
338
339 template <typename T, int Size>
340 inline Vector<T, Size> select (T trueVal, T falseVal, const Vector<bool, Size>& cond)
341 {
342         Vector<T, Size> res;
343         for (int i = 0; i < Size; i++)
344                 res[i] = cond[i] ? trueVal : falseVal;
345         return res;
346 }
347
348 // Component-wise selection.
349
350 template <typename T, int Size>
351 inline Vector<T, Size> select (const Vector<T, Size>& trueVal, const Vector<T, Size>& falseVal, const Vector<bool, Size>& cond)
352 {
353         Vector<T, Size> res;
354         for (int i = 0; i < Size; i++)
355                 res[i] = cond[i] ? trueVal[i] : falseVal[i];
356         return res;
357 }
358
359 // Absolute difference (abs(a - b))
360
361 template<typename T, int Size>
362 static inline Vector<T, Size> absDiff (const Vector<T, Size>& a, const Vector<T, Size>& b)
363 {
364         Vector<T, Size> res;
365
366         for (int ndx = 0; ndx < Size; ndx++)
367                 res[ndx] = (a[ndx] > b[ndx]) ? (a[ndx] - b[ndx]) : (b[ndx] - a[ndx]);
368
369         return res;
370 }
371
372 template<typename T, int Size>
373 inline tcu::Vector<T, Size> randomVector (de::Random& rnd, const tcu::Vector<T, Size>& minValue, const tcu::Vector<T, Size>& maxValue)
374 {
375         tcu::Vector<T, Size> res;
376
377         for (int ndx = 0; ndx < Size; ndx++)
378                 res[ndx] = de::randomScalar<T>(rnd, minValue[ndx], maxValue[ndx]);
379
380         return res;
381 }
382
383 inline Vector<float, 2> randomVec2 (de::Random& rnd)
384 {
385         return randomVector<float, 2>(rnd, tcu::Vector<float, 2>(0.0f), tcu::Vector<float, 2>(1.0f));
386 }
387
388 inline Vector<float, 3> randomVec3 (de::Random& rnd)
389 {
390         return randomVector<float, 3>(rnd, tcu::Vector<float, 3>(0.0f), tcu::Vector<float, 3>(1.0f));
391 }
392
393 inline Vector<float, 4> randomVec4 (de::Random& rnd)
394 {
395         return randomVector<float, 4>(rnd, tcu::Vector<float, 4>(0.0f), tcu::Vector<float, 4>(1.0f));
396 }
397
398 // Macros for component-wise ops.
399
400 #define TCU_DECLARE_VECTOR_UNARY_FUNC(FUNC_NAME, OP_NAME)       \
401 template <typename T, int Size>                                                         \
402 Vector<T, Size> FUNC_NAME (const Vector<T, Size>& v)            \
403 {                                                                                                                       \
404         Vector<T, Size> res;                                                                    \
405         for (int i = 0; i < Size; i++)                                                  \
406                 res.m_data[i] = OP_NAME(v.m_data[i]);                           \
407         return res;                                                                                             \
408 }
409
410 #define TCU_DECLARE_VECTOR_BINARY_FUNC(FUNC_NAME, OP_NAME)                                              \
411 template <typename T, int Size>                                                                                                 \
412 Vector<T, Size> FUNC_NAME (const Vector<T, Size>& a, const Vector<T, Size>& b)  \
413 {                                                                                                                                                               \
414         Vector<T, Size> res;                                                                                                            \
415         for (int i = 0; i < Size; i++)                                                                                          \
416                 res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i]);                                              \
417         return res;                                                                                                                                     \
418 }
419
420 #define TCU_DECLARE_VECTOR_TERNARY_FUNC(FUNC_NAME, OP_NAME)                                                                                                     \
421 template <typename T, int Size>                                                                                                                                                         \
422 Vector<T, Size> FUNC_NAME (const Vector<T, Size>& a, const Vector<T, Size>& b, const Vector<T, Size>& c)        \
423 {                                                                                                                                                                                                                       \
424         Vector<T, Size> res;                                                                                                                                                                    \
425         for (int i = 0; i < Size; i++)                                                                                                                                                  \
426                 res.m_data[i] = OP_NAME(a.m_data[i], b.m_data[i], c.m_data[i]);                                                                         \
427         return res;                                                                                                                                                                                             \
428 }
429
430 // \todo [2011-07-01 pyry] Add some prefix to vector funcs and remove this hack.
431 #if defined(min)
432 #       undef min
433 #endif
434 #if defined(max)
435 #       undef max
436 #endif
437
438 TCU_DECLARE_VECTOR_UNARY_FUNC(negate, negate)
439 TCU_DECLARE_VECTOR_UNARY_FUNC(bitwiseNot, bitwiseNot)
440 TCU_DECLARE_VECTOR_BINARY_FUNC(add, add)
441 TCU_DECLARE_VECTOR_BINARY_FUNC(sub, sub)
442 TCU_DECLARE_VECTOR_BINARY_FUNC(mul, mul)
443 TCU_DECLARE_VECTOR_BINARY_FUNC(div, div)
444 TCU_DECLARE_VECTOR_BINARY_FUNC(mod, mod)
445 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseAnd, bitwiseAnd)
446 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseOr, bitwiseOr)
447 TCU_DECLARE_VECTOR_BINARY_FUNC(bitwiseXor, bitwiseXor)
448 TCU_DECLARE_VECTOR_UNARY_FUNC(logicalNot, logicalNot)
449 TCU_DECLARE_VECTOR_BINARY_FUNC(logicalAnd, logicalAnd)
450 TCU_DECLARE_VECTOR_BINARY_FUNC(logicalOr, logicalOr)
451
452 TCU_DECLARE_VECTOR_UNARY_FUNC(radians, deFloatRadians)
453 TCU_DECLARE_VECTOR_UNARY_FUNC(degrees, deFloatDegrees)
454 TCU_DECLARE_VECTOR_UNARY_FUNC(sin, deFloatSin)
455 TCU_DECLARE_VECTOR_UNARY_FUNC(cos, deFloatCos)
456 TCU_DECLARE_VECTOR_UNARY_FUNC(tan, deFloatTan)
457 TCU_DECLARE_VECTOR_UNARY_FUNC(asin, deFloatAsin)
458 TCU_DECLARE_VECTOR_UNARY_FUNC(acos, deFloatAcos)
459 TCU_DECLARE_VECTOR_UNARY_FUNC(atan, deFloatAtanOver)
460 TCU_DECLARE_VECTOR_BINARY_FUNC(atan2, deFloatAtan2)
461 TCU_DECLARE_VECTOR_UNARY_FUNC(sinh, deFloatSinh)
462 TCU_DECLARE_VECTOR_UNARY_FUNC(cosh, deFloatCosh)
463 TCU_DECLARE_VECTOR_UNARY_FUNC(tanh, deFloatTanh)
464 TCU_DECLARE_VECTOR_UNARY_FUNC(asinh, deFloatAsinh)
465 TCU_DECLARE_VECTOR_UNARY_FUNC(acosh, deFloatAcosh)
466 TCU_DECLARE_VECTOR_UNARY_FUNC(atanh, deFloatAtanh)
467
468 TCU_DECLARE_VECTOR_BINARY_FUNC(pow, deFloatPow)
469 TCU_DECLARE_VECTOR_UNARY_FUNC(exp, deFloatExp)
470 TCU_DECLARE_VECTOR_UNARY_FUNC(log, deFloatLog)
471 TCU_DECLARE_VECTOR_UNARY_FUNC(exp2, deFloatExp2)
472 TCU_DECLARE_VECTOR_UNARY_FUNC(log2, deFloatLog2)
473 TCU_DECLARE_VECTOR_UNARY_FUNC(sqrt, deFloatSqrt)
474 TCU_DECLARE_VECTOR_UNARY_FUNC(inverseSqrt, deFloatRsq)
475
476 TCU_DECLARE_VECTOR_UNARY_FUNC(abs, de::abs)
477 TCU_DECLARE_VECTOR_UNARY_FUNC(sign, deFloatSign)
478 TCU_DECLARE_VECTOR_UNARY_FUNC(floor, deFloatFloor)
479 TCU_DECLARE_VECTOR_UNARY_FUNC(trunc, deFloatTrunc)
480 TCU_DECLARE_VECTOR_UNARY_FUNC(roundToEven, roundToEven)
481 TCU_DECLARE_VECTOR_UNARY_FUNC(ceil, deFloatCeil)
482 TCU_DECLARE_VECTOR_UNARY_FUNC(fract, deFloatFrac)
483 TCU_DECLARE_VECTOR_BINARY_FUNC(min, de::min)
484 TCU_DECLARE_VECTOR_BINARY_FUNC(max, de::max)
485 TCU_DECLARE_VECTOR_TERNARY_FUNC(clamp, de::clamp)
486 TCU_DECLARE_VECTOR_TERNARY_FUNC(mix, deFloatMix)
487 TCU_DECLARE_VECTOR_BINARY_FUNC(step, deFloatStep)
488 TCU_DECLARE_VECTOR_TERNARY_FUNC(smoothStep, deFloatSmoothStep)
489
490 } // tcu
491
492 #endif // _TCUVECTORUTIL_HPP