xref: /aosp_15_r20/external/deqp/framework/common/tcuVector.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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