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> 54 VecAccess<T, VecSize, Size>::VecAccess (Vector<T, VecSize>& v, int x, int y) 55 : m_vector(v) 56 { 57 DE_STATIC_ASSERT(Size == 2); 58 m_index[0] = x; 59 m_index[1] = y; 60 } 61 62 template <typename T, int VecSize, int Size> 63 VecAccess<T, VecSize, Size>::VecAccess (Vector<T, VecSize>& v, int x, int y, int z) 64 : m_vector(v) 65 { 66 DE_STATIC_ASSERT(Size == 3); 67 m_index[0] = x; 68 m_index[1] = y; 69 m_index[2] = z; 70 } 71 72 template <typename T, int VecSize, int Size> 73 VecAccess<T, VecSize, Size>::VecAccess (Vector<T, VecSize>& v, int x, int y, int z, int w) 74 : m_vector(v) 75 { 76 DE_STATIC_ASSERT(Size == 4); 77 m_index[0] = x; 78 m_index[1] = y; 79 m_index[2] = z; 80 m_index[3] = w; 81 } 82 83 template <typename T, int VecSize, int Size> 84 VecAccess<T, VecSize, Size>& VecAccess<T, VecSize, Size>::operator= (const Vector<T, Size>& v) 85 { 86 for (int i = 0; i < Size; i++) 87 m_vector.m_data[m_index[i]] = v.m_data[i]; 88 return *this; 89 } 90 91 // Vector class. 92 template <typename T, int Size> 93 class Vector 94 { 95 public: 96 typedef T Element; 97 enum 98 { 99 SIZE = Size, 100 }; 101 102 T m_data[Size]; 103 104 // Constructors. 105 explicit Vector (void); 106 explicit Vector (T s_); // replicate 107 Vector (T x_, T y_); 108 Vector (T x_, T y_, T z_); 109 Vector (T x_, T y_, T z_, T w_); 110 Vector (const Vector<T, Size>& v); 111 Vector (const T (&v)[Size]); 112 ~Vector (void); 113 114 const T* getPtr (void) const { return &m_data[0]; } 115 T* getPtr (void) { return &m_data[0]; } 116 117 // Read-only access. 118 T x (void) const { return m_data[0]; } 119 T y (void) const { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; } 120 T z (void) const { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; } 121 T w (void) const { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; } 122 123 // Read-write access. 124 T& x (void) { return m_data[0]; } 125 T& y (void) { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; } 126 T& z (void) { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; } 127 T& w (void) { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; } 128 129 // Writable accessors. 130 VecAccess<T, Size, 2> xy (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 1); } 131 VecAccess<T, Size, 2> xz (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 2); } 132 VecAccess<T, Size, 2> xw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 3); } 133 VecAccess<T, Size, 2> yz (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 2); } 134 VecAccess<T, Size, 2> yw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 3); } 135 VecAccess<T, Size, 2> zw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 2, 3); } 136 VecAccess<T, Size, 3> xyz (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 2); } 137 VecAccess<T, Size, 3> xyw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 3); } 138 VecAccess<T, Size, 3> xzw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 2, 3); } 139 VecAccess<T, Size, 3> zyx (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 2, 1, 0); } 140 VecAccess<T, Size, 3> yzw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 1, 2, 3); } 141 VecAccess<T, Size, 3> wzy (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 3, 2, 1); } 142 VecAccess<T, Size, 4> xyzw (void) { DE_ASSERT(Size >= 4); return VecAccess<T, Size, 4>(*this, 0, 1, 2, 3); } 143 144 // Swizzles. 145 const T& swizzle (int a) const { DE_ASSERT(a >= 0 && a < Size); return m_data[a]; } 146 Vector<T, 2> swizzle (int a, int b) const { DE_ASSERT(a >= 0 && a < Size); DE_ASSERT(b >= 0 && b < Size); return Vector<T, 2>(m_data[a], m_data[b]); } 147 Vector<T, 3> swizzle (int a, int b, int c) const { DE_ASSERT(a >= 0 && a < Size); DE_ASSERT(b >= 0 && b < Size); DE_ASSERT(c >= 0 && c < Size); return Vector<T, 3>(m_data[a], m_data[b], m_data[c]); } 148 Vector<T, 4> swizzle (int a, int b, int c, int d) const { DE_ASSERT(a >= 0 && a < Size); DE_ASSERT(b >= 0 && b < Size); DE_ASSERT(c >= 0 && c < Size); DE_ASSERT(d >= 0 && d < Size); return Vector<T, 4>(m_data[a], m_data[b], m_data[c], m_data[d]); } 149 150 Vector<float, Size> asFloat (void) const { return cast<float>(); } 151 Vector<int, Size> asInt (void) const { return cast<int>(); } 152 Vector<deUint32, Size> asUint (void) const { return cast<deUint32>(); } 153 Vector<bool, Size> asBool (void) const { return cast<bool>(); } 154 155 // Operators. 156 Vector<T, Size>& operator= (const Vector<T, Size>& v) { for (int i = 0; i < Size; i++) m_data[i] = v.m_data[i]; return *this; } 157 Vector<T, Size>& operator+= (const Vector<T, Size>& v); 158 159 const T& operator[] (int ndx) const { DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; } 160 T& operator[] (int ndx) { DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; } 161 162 bool operator== (const Vector<T, Size>& v) const { for (int i = 0; i < Size; i++) if (m_data[i] != v.m_data[i]) return false; return true; } 163 bool operator!= (const Vector<T, Size>& v) const { return !(*this == v); } 164 165 // Miscellaneous conversions. 166 template<typename NewT> 167 Vector<NewT, Size> cast (void) const; 168 169 template <int NewSize> 170 Vector<T, NewSize> toWidth (void) const; 171 }; 172 173 template <typename T, int Size> 174 inline Vector<T, Size>::Vector (void) 175 { 176 for (int i = 0; i < Size; i++) 177 m_data[i] = T(); 178 } 179 180 template <typename T, int Size> 181 inline Vector<T, Size>::Vector (T s) 182 { 183 for (int i = 0; i < Size; i++) 184 m_data[i] = s; 185 } 186 187 template <typename T, int Size> 188 inline Vector<T, Size>::Vector (T x_, T y_) 189 { 190 DE_STATIC_ASSERT(Size == 2); 191 m_data[0] = x_; 192 m_data[1] = y_; 193 } 194 195 template <typename T, int Size> 196 inline Vector<T, Size>::Vector (T x_, T y_, T z_) 197 { 198 DE_STATIC_ASSERT(Size == 3); 199 m_data[0] = x_; 200 m_data[1] = y_; 201 m_data[2] = z_; 202 } 203 204 template <typename T, int Size> 205 inline Vector<T, Size>::Vector (T x_, T y_, T z_, T w_) 206 { 207 DE_STATIC_ASSERT(Size == 4); 208 m_data[0] = x_; 209 m_data[1] = y_; 210 m_data[2] = z_; 211 m_data[3] = w_; 212 } 213 214 template <typename T, int Size> 215 inline Vector<T, Size>::Vector (const Vector<T, Size>& v) 216 { 217 for (int i = 0; i < Size; i++) 218 m_data[i] = v.m_data[i]; 219 } 220 221 template <typename T, int Size> 222 inline Vector<T, Size>::Vector (const T (&v)[Size]) 223 { 224 for (int i = 0; i < Size; i++) 225 m_data[i] = v[i]; 226 } 227 228 // VecAccess to Vector cast. 229 template <typename T, int VecSize, int Size> 230 VecAccess<T, VecSize, Size>::operator Vector<T, Size> (void) const 231 { 232 Vector<T, Size> vec; 233 for (int i = 0; i < Size; i++) 234 vec.m_data[i] = m_vector.m_data[m_index[i]]; 235 return vec; 236 } 237 238 // Type cast. 239 template <typename T, int Size> 240 template <typename NewT> 241 inline Vector<NewT, Size> Vector<T, Size>::cast (void) const 242 { 243 Vector<NewT, Size> res; 244 for (int i = 0; i < Size; i++) 245 res.m_data[i] = NewT(m_data[i]); 246 return res; 247 } 248 249 // Size cast. 250 template <typename T, int Size> 251 template <int NewSize> 252 inline Vector<T, NewSize> Vector<T, Size>::toWidth (void) const 253 { 254 Vector<T, NewSize> res; 255 int i; 256 for (i = 0; i < deMin32(Size, NewSize); i++) 257 res.m_data[i] = m_data[i]; 258 for (; i < NewSize; i++) 259 res.m_data[i] = T(0); 260 return res; 261 } 262 263 // \todo [petri] Other conversions! 264 265 template <typename T, int Size> 266 inline Vector<T, Size>::~Vector (void) 267 { 268 } 269 270 // Operators. 271 272 template <typename T, int Size> 273 inline Vector<T, Size> operator- (const Vector<T, Size>& a) 274 { 275 Vector<T, Size> res; 276 for (int i = 0; i < Size; i++) 277 res.m_data[i] = -a.m_data[i]; 278 return res; 279 } 280 281 template <typename T, int Size> 282 inline Vector<T, Size> operator+ (const Vector<T, Size>& a, const Vector<T, Size>& b) 283 { 284 Vector<T, Size> res; 285 for (int i = 0; i < Size; i++) 286 res.m_data[i] = a.m_data[i] + b.m_data[i]; 287 return res; 288 } 289 290 template <typename T, int Size> 291 inline Vector<T, Size> operator- (const Vector<T, Size>& a, const Vector<T, Size>& b) 292 { 293 Vector<T, Size> res; 294 for (int i = 0; i < Size; i++) 295 res.m_data[i] = a.m_data[i] - b.m_data[i]; 296 return res; 297 } 298 299 template <typename T, int Size> 300 inline Vector<T, Size> operator* (const Vector<T, Size>& a, const Vector<T, Size>& b) 301 { 302 Vector<T, Size> res; 303 for (int i = 0; i < Size; i++) 304 res.m_data[i] = a.m_data[i] * b.m_data[i]; 305 return res; 306 } 307 308 template <typename T, int Size> 309 inline Vector<T, Size> operator/ (const Vector<T, Size>& a, const Vector<T, Size>& b) 310 { 311 Vector<T, Size> res; 312 for (int i = 0; i < Size; i++) 313 res.m_data[i] = a.m_data[i] / b.m_data[i]; 314 return res; 315 } 316 317 template <typename T, int Size> 318 inline Vector<T, Size> operator<< (const Vector<T, Size>& a, const Vector<T, Size>& b) 319 { 320 Vector<T, Size> res; 321 for (int i = 0; i < Size; i++) 322 res.m_data[i] = a.m_data[i] << b.m_data[i]; 323 return res; 324 } 325 326 template <typename T, int Size> 327 inline Vector<T, Size> operator>> (const Vector<T, Size>& a, const Vector<T, Size>& b) 328 { 329 Vector<T, Size> res; 330 for (int i = 0; i < Size; i++) 331 res.m_data[i] = a.m_data[i] >> b.m_data[i]; 332 return res; 333 } 334 335 template <typename T, int Size> 336 inline Vector<T, Size> operator* (T s, const Vector<T, Size>& a) 337 { 338 Vector<T, Size> res; 339 for (int i = 0; i < Size; i++) 340 res.m_data[i] = s * a.m_data[i]; 341 return res; 342 } 343 344 template <typename T, int Size> 345 inline Vector<T, Size> operator+ (T s, const Vector<T, Size>& a) 346 { 347 Vector<T, Size> res; 348 for (int i = 0; i < Size; i++) 349 res.m_data[i] = s + a.m_data[i]; 350 return res; 351 } 352 353 template <typename T, int Size> 354 inline Vector<T, Size> operator- (T s, const Vector<T, Size>& a) 355 { 356 Vector<T, Size> res; 357 for (int i = 0; i < Size; i++) 358 res.m_data[i] = s - a.m_data[i]; 359 return res; 360 } 361 362 template <typename T, int Size> 363 inline Vector<T, Size> operator- (const Vector<T, Size>& a, T s) 364 { 365 Vector<T, Size> res; 366 for (int i = 0; i < Size; i++) 367 res.m_data[i] = a.m_data[i] - s; 368 return res; 369 } 370 371 template <typename T, int Size> 372 inline Vector<T, Size> operator/ (T s, const Vector<T, Size>& a) 373 { 374 Vector<T, Size> res; 375 for (int i = 0; i < Size; i++) 376 res.m_data[i] = s / a.m_data[i]; 377 return res; 378 } 379 380 template <typename T, int Size> 381 inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s) { return s * a; } 382 383 template <typename T, int Size> 384 inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s) { return s + a; } 385 386 template <typename T, int Size> 387 inline Vector<T, Size> operator/ (const Vector<T, Size>& a, T s) 388 { 389 Vector<T, Size> res; 390 for (int i = 0; i < Size; i++) 391 res.m_data[i] = a.m_data[i] / s; 392 return res; 393 } 394 395 template <typename T, int Size> 396 inline Vector<T, Size>& Vector<T, Size>::operator+= (const Vector<T, Size>& v) 397 { 398 for (int i = 0; i < Size; i++) 399 m_data[i] += v.m_data[i]; 400 return *this; 401 } 402 403 // Stream operator. 404 template <typename T, int Size> 405 std::ostream& operator<< (std::ostream& stream, const tcu::Vector<T, Size>& vec) 406 { 407 stream << "("; 408 for (int i = 0; i < Size; i++) 409 { 410 if (i != 0) 411 stream << ", "; 412 stream << vec.m_data[i]; 413 } 414 stream << ")"; 415 return stream; 416 } 417 418 } // tcu 419 420 #endif // _TCUVECTOR_HPP 421