1 #ifndef _TCUVECTOR_HPP
2 #define _TCUVECTOR_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 Generic vector template.
24 *//*--------------------------------------------------------------------*/
25
26 #include "tcuDefs.hpp"
27 #include "tcuVectorType.hpp"
28 #include "deInt32.h"
29
30 #include <ostream>
31
32 namespace tcu
33 {
34
35 // Accessor proxy class for Vectors.
36 template <typename T, int VecSize, int Size>
37 class VecAccess
38 {
39 public:
40 explicit VecAccess(Vector<T, VecSize> &v, int x, int y);
41 explicit VecAccess(Vector<T, VecSize> &v, int x, int y, int z);
42 explicit VecAccess(Vector<T, VecSize> &v, int x, int y, int z, int w);
43
44 VecAccess &operator=(const Vector<T, Size> &v);
45
46 operator Vector<T, Size>(void) const;
47
48 private:
49 Vector<T, VecSize> &m_vector;
50 int m_index[Size];
51 };
52
53 template <typename T, int VecSize, int Size>
VecAccess(Vector<T,VecSize> & v,int x,int y)54 VecAccess<T, VecSize, Size>::VecAccess(Vector<T, VecSize> &v, int x, int y) : m_vector(v)
55 {
56 DE_STATIC_ASSERT(Size == 2);
57 m_index[0] = x;
58 m_index[1] = y;
59 }
60
61 template <typename T, int VecSize, int Size>
VecAccess(Vector<T,VecSize> & v,int x,int y,int z)62 VecAccess<T, VecSize, Size>::VecAccess(Vector<T, VecSize> &v, int x, int y, int z) : m_vector(v)
63 {
64 DE_STATIC_ASSERT(Size == 3);
65 m_index[0] = x;
66 m_index[1] = y;
67 m_index[2] = z;
68 }
69
70 template <typename T, int VecSize, int Size>
VecAccess(Vector<T,VecSize> & v,int x,int y,int z,int w)71 VecAccess<T, VecSize, Size>::VecAccess(Vector<T, VecSize> &v, int x, int y, int z, int w) : m_vector(v)
72 {
73 DE_STATIC_ASSERT(Size == 4);
74 m_index[0] = x;
75 m_index[1] = y;
76 m_index[2] = z;
77 m_index[3] = w;
78 }
79
80 template <typename T, int VecSize, int Size>
operator =(const Vector<T,Size> & v)81 VecAccess<T, VecSize, Size> &VecAccess<T, VecSize, Size>::operator=(const Vector<T, Size> &v)
82 {
83 for (int i = 0; i < Size; i++)
84 m_vector.m_data[m_index[i]] = v.m_data[i];
85 return *this;
86 }
87
88 // Vector class.
89 template <typename T, int Size>
90 class Vector
91 {
92 public:
93 typedef T Element;
94 enum
95 {
96 SIZE = Size,
97 };
98
99 T m_data[Size];
100
101 // Constructors.
102 explicit Vector(void);
103 explicit Vector(T s_); // replicate
104 Vector(T x_, T y_);
105 Vector(T x_, T y_, T z_);
106 Vector(T x_, T y_, T z_, T w_);
107 Vector(const Vector<T, Size> &v);
108 Vector(const T (&v)[Size]);
109
getPtr(void) const110 const T *getPtr(void) const
111 {
112 return &m_data[0];
113 }
getPtr(void)114 T *getPtr(void)
115 {
116 return &m_data[0];
117 }
118
119 // Read-only access.
x(void) const120 T x(void) const
121 {
122 return m_data[0];
123 }
y(void) const124 T y(void) const
125 {
126 DE_STATIC_ASSERT(Size >= 2);
127 return m_data[1];
128 }
z(void) const129 T z(void) const
130 {
131 DE_STATIC_ASSERT(Size >= 3);
132 return m_data[2];
133 }
w(void) const134 T w(void) const
135 {
136 DE_STATIC_ASSERT(Size >= 4);
137 return m_data[3];
138 }
139
140 // Read-write access.
x(void)141 T &x(void)
142 {
143 return m_data[0];
144 }
y(void)145 T &y(void)
146 {
147 DE_STATIC_ASSERT(Size >= 2);
148 return m_data[1];
149 }
z(void)150 T &z(void)
151 {
152 DE_STATIC_ASSERT(Size >= 3);
153 return m_data[2];
154 }
w(void)155 T &w(void)
156 {
157 DE_STATIC_ASSERT(Size >= 4);
158 return m_data[3];
159 }
160
161 // Writable accessors.
xy(void)162 VecAccess<T, Size, 2> xy(void)
163 {
164 DE_ASSERT(Size >= 2);
165 return VecAccess<T, Size, 2>(*this, 0, 1);
166 }
xz(void)167 VecAccess<T, Size, 2> xz(void)
168 {
169 DE_ASSERT(Size >= 2);
170 return VecAccess<T, Size, 2>(*this, 0, 2);
171 }
xw(void)172 VecAccess<T, Size, 2> xw(void)
173 {
174 DE_ASSERT(Size >= 2);
175 return VecAccess<T, Size, 2>(*this, 0, 3);
176 }
yz(void)177 VecAccess<T, Size, 2> yz(void)
178 {
179 DE_ASSERT(Size >= 2);
180 return VecAccess<T, Size, 2>(*this, 1, 2);
181 }
yw(void)182 VecAccess<T, Size, 2> yw(void)
183 {
184 DE_ASSERT(Size >= 2);
185 return VecAccess<T, Size, 2>(*this, 1, 3);
186 }
zw(void)187 VecAccess<T, Size, 2> zw(void)
188 {
189 DE_ASSERT(Size >= 2);
190 return VecAccess<T, Size, 2>(*this, 2, 3);
191 }
xyz(void)192 VecAccess<T, Size, 3> xyz(void)
193 {
194 DE_ASSERT(Size >= 3);
195 return VecAccess<T, Size, 3>(*this, 0, 1, 2);
196 }
xyw(void)197 VecAccess<T, Size, 3> xyw(void)
198 {
199 DE_ASSERT(Size >= 3);
200 return VecAccess<T, Size, 3>(*this, 0, 1, 3);
201 }
xzw(void)202 VecAccess<T, Size, 3> xzw(void)
203 {
204 DE_ASSERT(Size >= 3);
205 return VecAccess<T, Size, 3>(*this, 0, 2, 3);
206 }
zyx(void)207 VecAccess<T, Size, 3> zyx(void)
208 {
209 DE_ASSERT(Size >= 3);
210 return VecAccess<T, Size, 3>(*this, 2, 1, 0);
211 }
yzw(void)212 VecAccess<T, Size, 3> yzw(void)
213 {
214 DE_ASSERT(Size >= 3);
215 return VecAccess<T, Size, 3>(*this, 1, 2, 3);
216 }
wzy(void)217 VecAccess<T, Size, 3> wzy(void)
218 {
219 DE_ASSERT(Size >= 3);
220 return VecAccess<T, Size, 3>(*this, 3, 2, 1);
221 }
xyzw(void)222 VecAccess<T, Size, 4> xyzw(void)
223 {
224 DE_ASSERT(Size >= 4);
225 return VecAccess<T, Size, 4>(*this, 0, 1, 2, 3);
226 }
227
228 // Swizzles.
swizzle(int a) const229 Vector<T, 1> swizzle(int a) const
230 {
231 DE_ASSERT(a >= 0 && a < Size);
232 return Vector<T, 1>(m_data[a]);
233 }
swizzle(int a,int b) const234 Vector<T, 2> swizzle(int a, int b) const
235 {
236 DE_ASSERT(a >= 0 && a < Size);
237 DE_ASSERT(b >= 0 && b < Size);
238 return Vector<T, 2>(m_data[a], m_data[b]);
239 }
swizzle(int a,int b,int c) const240 Vector<T, 3> swizzle(int a, int b, int c) const
241 {
242 DE_ASSERT(a >= 0 && a < Size);
243 DE_ASSERT(b >= 0 && b < Size);
244 DE_ASSERT(c >= 0 && c < Size);
245 return Vector<T, 3>(m_data[a], m_data[b], m_data[c]);
246 }
swizzle(int a,int b,int c,int d) const247 Vector<T, 4> swizzle(int a, int b, int c, int d) const
248 {
249 DE_ASSERT(a >= 0 && a < Size);
250 DE_ASSERT(b >= 0 && b < Size);
251 DE_ASSERT(c >= 0 && c < Size);
252 DE_ASSERT(d >= 0 && d < Size);
253 return Vector<T, 4>(m_data[a], m_data[b], m_data[c], m_data[d]);
254 }
255
asFloat(void) const256 Vector<float, Size> asFloat(void) const
257 {
258 return cast<float>();
259 }
asInt(void) const260 Vector<int, Size> asInt(void) const
261 {
262 return cast<int>();
263 }
asUint(void) const264 Vector<uint32_t, Size> asUint(void) const
265 {
266 return cast<uint32_t>();
267 }
asBool(void) const268 Vector<bool, Size> asBool(void) const
269 {
270 return cast<bool>();
271 }
272
273 // Operators.
274 Vector<T, Size> &operator+=(const Vector<T, Size> &v);
275 Vector<T, Size> &operator-=(const Vector<T, Size> &v);
276 Vector<T, Size> &operator=(const Vector<T, Size> &v);
277
operator [](int ndx) const278 const T &operator[](int ndx) const
279 {
280 DE_ASSERT(de::inBounds(ndx, 0, Size));
281 return m_data[ndx];
282 }
operator [](int ndx)283 T &operator[](int ndx)
284 {
285 DE_ASSERT(de::inBounds(ndx, 0, Size));
286 return m_data[ndx];
287 }
288
operator ==(const Vector<T,Size> & v) const289 bool operator==(const Vector<T, Size> &v) const
290 {
291 for (int i = 0; i < Size; i++)
292 if (m_data[i] != v.m_data[i])
293 return false;
294 return true;
295 }
operator !=(const Vector<T,Size> & v) const296 bool operator!=(const Vector<T, Size> &v) const
297 {
298 return !(*this == v);
299 }
300
301 // Miscellaneous conversions.
302 template <typename NewT>
303 Vector<NewT, Size> cast(void) const;
304
305 template <typename NewT>
306 Vector<NewT, Size> bitCast(void) const;
307
308 template <int NewSize>
309 Vector<T, NewSize> toWidth(void) const;
310 } DE_WARN_UNUSED_TYPE;
311
312 template <typename T, int Size>
Vector(void)313 inline Vector<T, Size>::Vector(void)
314 {
315 for (int i = 0; i < Size; i++)
316 m_data[i] = T();
317 }
318
319 template <typename T, int Size>
Vector(T s)320 inline Vector<T, Size>::Vector(T s)
321 {
322 for (int i = 0; i < Size; i++)
323 m_data[i] = s;
324 }
325
326 template <typename T, int Size>
Vector(T x_,T y_)327 inline Vector<T, Size>::Vector(T x_, T y_)
328 {
329 DE_STATIC_ASSERT(Size == 2);
330 m_data[0] = x_;
331 m_data[1] = y_;
332 }
333
334 template <typename T, int Size>
Vector(T x_,T y_,T z_)335 inline Vector<T, Size>::Vector(T x_, T y_, T z_)
336 {
337 DE_STATIC_ASSERT(Size == 3);
338 m_data[0] = x_;
339 m_data[1] = y_;
340 m_data[2] = z_;
341 }
342
343 template <typename T, int Size>
Vector(T x_,T y_,T z_,T w_)344 inline Vector<T, Size>::Vector(T x_, T y_, T z_, T w_)
345 {
346 DE_STATIC_ASSERT(Size == 4);
347 m_data[0] = x_;
348 m_data[1] = y_;
349 m_data[2] = z_;
350 m_data[3] = w_;
351 }
352
353 template <typename T, int Size>
Vector(const Vector<T,Size> & v)354 inline Vector<T, Size>::Vector(const Vector<T, Size> &v)
355 {
356 for (int i = 0; i < Size; i++)
357 m_data[i] = v.m_data[i];
358 }
359
360 template <typename T, int Size>
operator =(const Vector<T,Size> & v)361 inline Vector<T, Size> &Vector<T, Size>::operator=(const Vector<T, Size> &v)
362 {
363 for (int i = 0; i < Size; i++)
364 m_data[i] = v.m_data[i];
365 return *this;
366 }
367
368 template <typename T, int Size>
Vector(const T (& v)[Size])369 inline Vector<T, Size>::Vector(const T (&v)[Size])
370 {
371 for (int i = 0; i < Size; i++)
372 m_data[i] = v[i];
373 }
374
375 // VecAccess to Vector cast.
376 template <typename T, int VecSize, int Size>
operator Vector<T,Size>(void) const377 VecAccess<T, VecSize, Size>::operator Vector<T, Size>(void) const
378 {
379 Vector<T, Size> vec;
380 for (int i = 0; i < Size; i++)
381 vec.m_data[i] = m_vector.m_data[m_index[i]];
382 return vec;
383 }
384
385 // Type cast.
386 template <typename T, int Size>
387 template <typename NewT>
cast(void) const388 inline Vector<NewT, Size> Vector<T, Size>::cast(void) const
389 {
390 Vector<NewT, Size> res;
391 for (int i = 0; i < Size; i++)
392 res.m_data[i] = NewT(m_data[i]);
393 return res;
394 }
395
396 // Bit-exact reinterpret cast.
397 template <typename T, int Size>
398 template <typename NewT>
bitCast(void) const399 inline Vector<NewT, Size> Vector<T, Size>::bitCast(void) const
400 {
401 Vector<NewT, Size> res;
402 DE_STATIC_ASSERT(sizeof(res.m_data) == sizeof(m_data));
403 memcpy(res.m_data, m_data, sizeof(m_data));
404 return res;
405 }
406
407 // Size cast.
408 template <typename T, int Size>
409 template <int NewSize>
toWidth(void) const410 inline Vector<T, NewSize> Vector<T, Size>::toWidth(void) const
411 {
412 Vector<T, NewSize> res;
413 int i;
414 for (i = 0; i < deMin32(Size, NewSize); i++)
415 res.m_data[i] = m_data[i];
416 for (; i < NewSize; i++)
417 res.m_data[i] = T(0);
418 return res;
419 }
420
421 // Operators.
422
423 template <typename T, int Size>
operator -(const Vector<T,Size> & a)424 inline Vector<T, Size> operator-(const Vector<T, Size> &a)
425 {
426 Vector<T, Size> res;
427 for (int i = 0; i < Size; i++)
428 res.m_data[i] = -a.m_data[i];
429 return res;
430 }
431
432 template <typename T, int Size>
operator +(const Vector<T,Size> & a,const Vector<T,Size> & b)433 inline Vector<T, Size> operator+(const Vector<T, Size> &a, const Vector<T, Size> &b)
434 {
435 Vector<T, Size> res;
436 for (int i = 0; i < Size; i++)
437 res.m_data[i] = a.m_data[i] + b.m_data[i];
438 return res;
439 }
440
441 template <typename T, int Size>
operator -(const Vector<T,Size> & a,const Vector<T,Size> & b)442 inline Vector<T, Size> operator-(const Vector<T, Size> &a, const Vector<T, Size> &b)
443 {
444 Vector<T, Size> res;
445 for (int i = 0; i < Size; i++)
446 res.m_data[i] = a.m_data[i] - b.m_data[i];
447 return res;
448 }
449
450 template <typename T, int Size>
operator *(const Vector<T,Size> & a,const Vector<T,Size> & b)451 inline Vector<T, Size> operator*(const Vector<T, Size> &a, const Vector<T, Size> &b)
452 {
453 Vector<T, Size> res;
454 for (int i = 0; i < Size; i++)
455 res.m_data[i] = a.m_data[i] * b.m_data[i];
456 return res;
457 }
458
459 template <typename T, int Size>
operator /(const Vector<T,Size> & a,const Vector<T,Size> & b)460 inline Vector<T, Size> operator/(const Vector<T, Size> &a, const Vector<T, Size> &b)
461 {
462 Vector<T, Size> res;
463 for (int i = 0; i < Size; i++)
464 res.m_data[i] = a.m_data[i] / b.m_data[i];
465 return res;
466 }
467
468 template <typename T, int Size>
operator <<(const Vector<T,Size> & a,const Vector<T,Size> & b)469 inline Vector<T, Size> operator<<(const Vector<T, Size> &a, const Vector<T, Size> &b)
470 {
471 Vector<T, Size> res;
472 for (int i = 0; i < Size; i++)
473 res.m_data[i] = a.m_data[i] << b.m_data[i];
474 return res;
475 }
476
477 template <typename T, int Size>
operator >>(const Vector<T,Size> & a,const Vector<T,Size> & b)478 inline Vector<T, Size> operator>>(const Vector<T, Size> &a, const Vector<T, Size> &b)
479 {
480 Vector<T, Size> res;
481 for (int i = 0; i < Size; i++)
482 res.m_data[i] = a.m_data[i] >> b.m_data[i];
483 return res;
484 }
485
486 template <typename T, int Size>
operator *(T s,const Vector<T,Size> & a)487 inline Vector<T, Size> operator*(T s, const Vector<T, Size> &a)
488 {
489 Vector<T, Size> res;
490 for (int i = 0; i < Size; i++)
491 res.m_data[i] = s * a.m_data[i];
492 return res;
493 }
494
495 template <typename T, int Size>
operator +(T s,const Vector<T,Size> & a)496 inline Vector<T, Size> operator+(T s, const Vector<T, Size> &a)
497 {
498 Vector<T, Size> res;
499 for (int i = 0; i < Size; i++)
500 res.m_data[i] = s + a.m_data[i];
501 return res;
502 }
503
504 template <typename T, int Size>
operator -(T s,const Vector<T,Size> & a)505 inline Vector<T, Size> operator-(T s, const Vector<T, Size> &a)
506 {
507 Vector<T, Size> res;
508 for (int i = 0; i < Size; i++)
509 res.m_data[i] = s - a.m_data[i];
510 return res;
511 }
512
513 template <typename T, int Size>
operator -(const Vector<T,Size> & a,T s)514 inline Vector<T, Size> operator-(const Vector<T, Size> &a, T s)
515 {
516 Vector<T, Size> res;
517 for (int i = 0; i < Size; i++)
518 res.m_data[i] = a.m_data[i] - s;
519 return res;
520 }
521
522 template <typename T, int Size>
operator /(T s,const Vector<T,Size> & a)523 inline Vector<T, Size> operator/(T s, const Vector<T, Size> &a)
524 {
525 Vector<T, Size> res;
526 for (int i = 0; i < Size; i++)
527 res.m_data[i] = s / a.m_data[i];
528 return res;
529 }
530
531 template <typename T, int Size>
operator *(const Vector<T,Size> & a,T s)532 inline Vector<T, Size> operator*(const Vector<T, Size> &a, T s)
533 {
534 return s * a;
535 }
536
537 template <typename T, int Size>
operator +(const Vector<T,Size> & a,T s)538 inline Vector<T, Size> operator+(const Vector<T, Size> &a, T s)
539 {
540 return s + a;
541 }
542
543 template <typename T, int Size>
operator /(const Vector<T,Size> & a,T s)544 inline Vector<T, Size> operator/(const Vector<T, Size> &a, T s)
545 {
546 Vector<T, Size> res;
547 for (int i = 0; i < Size; i++)
548 res.m_data[i] = a.m_data[i] / s;
549 return res;
550 }
551
552 template <typename T, int Size>
operator +=(const Vector<T,Size> & v)553 inline Vector<T, Size> &Vector<T, Size>::operator+=(const Vector<T, Size> &v)
554 {
555 for (int i = 0; i < Size; i++)
556 m_data[i] += v.m_data[i];
557 return *this;
558 }
559
560 template <typename T, int Size>
operator -=(const Vector<T,Size> & v)561 inline Vector<T, Size> &Vector<T, Size>::operator-=(const Vector<T, Size> &v)
562 {
563 for (int i = 0; i < Size; i++)
564 m_data[i] -= v.m_data[i];
565 return *this;
566 }
567
568 // Stream operator.
569 template <typename T, int Size>
operator <<(std::ostream & stream,const tcu::Vector<T,Size> & vec)570 std::ostream &operator<<(std::ostream &stream, const tcu::Vector<T, Size> &vec)
571 {
572 stream << "(";
573 for (int i = 0; i < Size; i++)
574 {
575 if (i != 0)
576 stream << ", ";
577 stream << vec.m_data[i];
578 }
579 stream << ")";
580 return stream;
581 }
582
583 } // namespace tcu
584
585 #endif // _TCUVECTOR_HPP
586