diff options
Diffstat (limited to 'include/pixelflinger2/pixelflinger2_vector4.h')
-rw-r--r-- | include/pixelflinger2/pixelflinger2_vector4.h | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/include/pixelflinger2/pixelflinger2_vector4.h b/include/pixelflinger2/pixelflinger2_vector4.h new file mode 100644 index 0000000..a77bda8 --- /dev/null +++ b/include/pixelflinger2/pixelflinger2_vector4.h @@ -0,0 +1,199 @@ +/** + ** + ** Copyright 2010, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ + +#ifndef _PIXELFLINGER2_VECTOR4_H_ +#define _PIXELFLINGER2_VECTOR4_H_ + +#ifdef __cplusplus + +template <typename Type> struct Vec4 { + union { + struct { Type x, y, z, w; }; + struct { Type r, g, b, a; }; + struct { Type S, T, R, Q; }; +#if !USE_FIXED_POINT + float f[4]; + unsigned u[4]; + int i[4]; +#endif +#if defined(__ARM_HAVE_NEON) && USE_NEON + float32x4_t f4; +#endif + }; + + //Vec4() : x(0), y(0), z(0), w(0) {} + Vec4() {} + Vec4(Type X, Type Y, Type Z, Type W) : x(X), y(Y), z(Z), w(W) {} + Vec4(Type X) : x(X), y(X), z(X), w(X) {} + +#define VECTOR4_OP_UNARY(op,rhs) { \ +x op rhs.x; \ +y op rhs.y; \ +z op rhs.z; \ +w op rhs.w; } + +#define VECTOR4_OP_UNARY_SCALAR(op,rhs) { \ +x op rhs; \ +y op rhs; \ +z op rhs; \ +w op rhs; } + + inline void operator += (const Vec4<Type> & rhs) __attribute__((always_inline)) + VECTOR4_OP_UNARY(+=,rhs) + inline void operator -= (const Vec4<Type> & rhs) __attribute__((always_inline)) + VECTOR4_OP_UNARY(-=,rhs) + inline void operator *= (const Vec4<Type> & rhs) __attribute__((always_inline)) + VECTOR4_OP_UNARY(*=,rhs) + inline void operator /= (const Vec4<Type> & rhs) __attribute__((always_inline)) + VECTOR4_OP_UNARY(/=,rhs) + inline void operator *= (Type rhs) __attribute__((always_inline)) + VECTOR4_OP_UNARY_SCALAR(*=,rhs) + inline void operator /= (Type rhs) __attribute__((always_inline)) + VECTOR4_OP_UNARY_SCALAR(/=,rhs) + + inline Vec4 operator+(const Vec4 & rhs) const + { Vec4 res = *this; res += rhs; return res; } + +#undef VECTOR4_OP_UNARY +#undef VECTOR4_OP_UNARY_SCALAR + + void CrossProduct3(const Vec4<Type> & lhs, const Vec4<Type> & rhs) + { + x = lhs.y * rhs.z - lhs.z * rhs.y; + y = lhs.z * rhs.x - lhs.x * rhs.z; + z = lhs.y * rhs.x - lhs.x * rhs.y; + w = 0; + } + + void LShr(const unsigned shift) { u[0] >>= shift; u[1] >>= shift; u[2] >>= shift; u[3] >>= shift; } + void AShr(const unsigned shift) { i[0] >>= shift; i[1] >>= shift; i[2] >>= shift; i[3] >>= shift; } + + bool operator==(const Vec4 & rhs) const { return u[0] == rhs.u[0] && u[1] == rhs.u[1] && u[2] == rhs.u[2] && u[3] == rhs.u[3]; } + bool operator!=(const Vec4 & rhs) const { return !(*this == rhs); } +}; + +#if defined(__ARM_HAVE_NEON) && USE_NEON +template <> inline void Vec4<float>::operator += (const Vec4<float> & rhs) __attribute__((always_inline)); +template <> inline void Vec4<float>::operator += (const Vec4<float> & rhs) +{ f4 = vaddq_f32(f4, rhs.f4); } +template <> inline void Vec4<float>::operator -= (const Vec4<float> & rhs) __attribute__((always_inline)); +template <> inline void Vec4<float>::operator -= (const Vec4<float> & rhs) +{ f4 = vsubq_f32(f4, rhs.f4); } +template <> inline void Vec4<float>::operator *= (float rhs) __attribute__((always_inline)); +template <> inline void Vec4<float>::operator *= (float rhs) +{ f4 = vmulq_n_f32(f4, rhs); } +template <> inline void Vec4<float>::operator /= (float rhs) __attribute__((always_inline)); +template <> inline void Vec4<float>::operator /= (float rhs) +{ f4 = vmulq_n_f32(f4, 1 / rhs); } +#endif // #if defined(__ARM_HAVE_NEON) && USE_NEON + +#if USE_FIXED_POINT +deprecated, should be removed +/*#define FIXED_POINT_ONE 0x10000 +#define FIXED_POINT_SHIFT 16 +struct FixedPoint +{ + int val; + //FixedPoint() {} + //explicit FixedPoint(int v) : val(v << FIXED_POINT_SHIFT) {} + //explicit FixedPoint(float v) : val(v * (2 << FIXED_POINT_SHIFT)) {} + //explicit FixedPoint(double v) : val(v * (2 << FIXED_POINT_SHIFT)) {} + static FixedPoint From(int v) { FixedPoint x; x.val = v << FIXED_POINT_SHIFT; return x; } + static FixedPoint From(unsigned v) { FixedPoint x; x.val = v << FIXED_POINT_SHIFT; return x; } + static FixedPoint From(float v) { FixedPoint x; x.val = v * (2 << FIXED_POINT_SHIFT); return x; } + static FixedPoint One() { FixedPoint x; x.val = FIXED_POINT_ONE; return x; } + static FixedPoint Zero() { FixedPoint x; x.val = 0; return x; } + FixedPoint operator-() const + { + FixedPoint res; + res.val = -val; + return res; + } + FixedPoint operator+(const FixedPoint & rhs) const + { + FixedPoint res; + res.val = val + rhs.val; + return res; + } + FixedPoint operator-(const FixedPoint & rhs) const + { + FixedPoint res; + res.val = val - rhs.val; + return res; + } + FixedPoint operator*(const FixedPoint & rhs) const + { + FixedPoint res; + res.val = (val >> 8) * (rhs.val >> 8); + return res; + } + FixedPoint operator/(const FixedPoint & rhs) const + { + FixedPoint res; + + long long lh = (long long)val << 32, rh = rhs.val | 1; + lh /= rh; + rh = (lh >> 16) & 0xffffffffL; + res.val = rh; + return res; + + //res.val = ((val << 2) / (rhs.val >> 6 | 1)) << 8; + //return res; + } + void operator+=(const FixedPoint & rhs) { val += rhs.val; } + void operator-=(const FixedPoint & rhs) { val += rhs.val; } + void operator*=(const FixedPoint & rhs) { *this = *this * rhs; } + void operator/=(const FixedPoint & rhs) { *this = *this / rhs; } + + bool operator<(const FixedPoint & rhs) const { return val < rhs.val; } + bool operator>(const FixedPoint & rhs) const { return val > rhs.val; } + bool operator<=(const FixedPoint & rhs) const { return val <= rhs.val; } + bool operator>=(const FixedPoint & rhs) const { return val >= rhs.val; } + bool operator==(const FixedPoint & rhs) const { return val == rhs.val; } + bool operator!=(const FixedPoint & rhs) const { return val != rhs.val; } + + operator int() const { return val >> FIXED_POINT_SHIFT; } + operator unsigned() const { return val >> FIXED_POINT_SHIFT; } + operator float() const { return (float)val / FIXED_POINT_ONE; } +}; + +typedef FixedPoint VectorComp_t; +typedef Vec4<VectorComp_t> Vector4; +#define Vector4_CTR(x,y,z,w) Vector4(FixedPoint::From(x), FixedPoint::From(y), \ + FixedPoint::From(z), FixedPoint::From(w)) +#define VectorComp_t_CTR(x) FixedPoint::From(x) +#define VectorComp_t_Zero FixedPoint::Zero() +#define VectorComp_t_One FixedPoint::One()*/ + +#else // if USE_FIXED_POINT + +typedef float VectorComp_t; +typedef struct Vec4<VectorComp_t> Vector4; +#define Vector4_CTR(x,y,z,w) Vector4(x,y,z,w) +#define VectorComp_t_CTR(x) (float)(x) +#define VectorComp_t_Zero 0 +#define VectorComp_t_One 1 + +#endif // if USE_FIXED_POINT + +#else // #ifdef __cplusplus + +typedef float Vector4 [4]; + +#endif // #ifdef __cplusplus + +#endif // #ifndef _PIXELFLINGER2_VECTOR4_H_
\ No newline at end of file |