From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- Runtime/Math/Simd/float4.h | 397 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100644 Runtime/Math/Simd/float4.h (limited to 'Runtime/Math/Simd/float4.h') diff --git a/Runtime/Math/Simd/float4.h b/Runtime/Math/Simd/float4.h new file mode 100644 index 0000000..7b653e6 --- /dev/null +++ b/Runtime/Math/Simd/float4.h @@ -0,0 +1,397 @@ +#ifndef SIMD_FLOAT4_H +#define SIMD_FLOAT4_H + +#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h" + +#include "Runtime/Math/Simd/intrinsic.h" + +#include "Runtime/Math/Simd/bool4.h" +#include "Runtime/Math/Simd/float1.h" + +namespace math +{ + +template struct ATTRIBUTE_ALIGN(ALIGN4F) vecexp4 : T +{ + typedef T value_type; + typedef typename T::scalar_type scalar_type; + typedef typename T::packed_type packed_type; + + MECANIM_FORCE_INLINE vecexp4() {} + + MECANIM_FORCE_INLINE vecexp4(vecexp4 const& e):value_type(e) { } + + template MECANIM_FORCE_INLINE vecexp4(const vecexp4 &e):value_type(e){ } + + MECANIM_FORCE_INLINE vecexp4(scalar_type const& x, scalar_type const& y, scalar_type const& z, scalar_type const& w):value_type(x,y,z,w) { } + + MECANIM_FORCE_INLINE vecexp4(value_type const& r):value_type(r) { } + + //template MECANIM_FORCE_INLINE vecexp4(const vecexp1 &x, const vecexp1 &y, const vecexp1 &z, const vecexp1 &w) { + // value_type::v = Vcombine( x.eval(), y.eval(), z.eval(), w.eval() ); + //} + MECANIM_FORCE_INLINE vecexp4(const float1 &x, const float1 &y, const float1 &z, const float1 &w) { + value_type::v = Vcombine( x.eval(), y.eval(), z.eval(), w.eval() ); + } + + MECANIM_FORCE_INLINE vecexp4 &operator=(const vecexp4 &l) { value_type::operator =(l); return *this; } + + template MECANIM_FORCE_INLINE vecexp4 &operator=(const vecexp4 &e) { + value_type::v = e.eval(); return *this; + } + + template MECANIM_FORCE_INLINE vecexp4 &operator=(const vecexp1 &e) { + value_type::v = e.eval(); return *this; + } + + MECANIM_FORCE_INLINE const vecexp4 &operator+() const { return *this; } + MECANIM_FORCE_INLINE vecexp4 operator-() const { return vecexp4(Vneg( value_type::eval() )); } +}; + +template struct ATTRIBUTE_ALIGN(ALIGN4F) swizzle1 +{ + typedef SCALAR scalar_type; + typedef LHS_VECTOR packed_type; + typedef RHS_VECTOR rhs_packed_type; + + enum{ + RHS_SWZ = RHS_MASK, + LHS_SWZ = LHS_MASK + }; + + + packed_type v; + + MECANIM_FORCE_INLINE swizzle1(packed_type vector):v(vector) {} + + MECANIM_FORCE_INLINE swizzle1 &operator=(const scalar_type &s) { v = Vswizzle::lhs(v, Vloadsf(s)); return *this; } + + MECANIM_FORCE_INLINE scalar_type tofloat() { return Vstoresf( Vswizzle::rhs(v) ); } + + MECANIM_FORCE_INLINE rhs_packed_type eval()const{ return Vswizzle::rhs(v); } +private: + + + MECANIM_FORCE_INLINE swizzle1 &operator=(const swizzle1 &s) {return *this;} +}; + +template struct ATTRIBUTE_ALIGN(ALIGN4F) swizzle +{ + typedef SCALAR scalar_type; + typedef VECTOR packed_type; + + enum{ + RHS_SWZ = MASK + }; + + MECANIM_FORCE_INLINE swizzle(packed_type const& vector):v(vector) {} + + MECANIM_FORCE_INLINE packed_type eval()const{ return Vswizzle::rhs(v); } + +protected: + packed_type v; +}; + +struct ATTRIBUTE_ALIGN(ALIGN4F) vec4 +{ + typedef float scalar_type; + typedef vec4f packed_type; + typedef vec4f const& const_reference_packed_type; + typedef vec4f& reference_packed_type; + + enum{ + RHS_SWZ = kXYZW + }; + + MECANIM_FORCE_INLINE vec4() {} + + MECANIM_FORCE_INLINE vec4(scalar_type x, scalar_type y, scalar_type z, scalar_type w):v(Vload4sf(x,y,z,w)) { } + + MECANIM_FORCE_INLINE vec4(scalar_type s):v(Vloadsf(s)) { } + + MECANIM_FORCE_INLINE vec4(packed_type vector):v(vector){ } + + template MECANIM_FORCE_INLINE vec4(const T& vector):v(vector.eval()){ } + + MECANIM_FORCE_INLINE vec4 &operator=(const vec4 &l) { + SIMD_ASSERT_IF(!l.IsFinite()); + v = l.v; + return *this; + } + + MECANIM_FORCE_INLINE packed_type eval()const{ return v; } + + inline bool IsFinite ()const + { + return ::IsFinite( x().tofloat() ) & ::IsFinite( y().tofloat() ) & ::IsFinite( z().tofloat() ) & ::IsFinite( w().tofloat() ); + } + + MECANIM_FORCE_INLINE vecexp1< swizzle1 > x()const { return vecexp1< swizzle1 >(v); } + MECANIM_FORCE_INLINE vecexp1< swizzle1 > y()const { return vecexp1< swizzle1 >(v); } + MECANIM_FORCE_INLINE vecexp1< swizzle1 > z()const { return vecexp1< swizzle1 >(v); } + MECANIM_FORCE_INLINE vecexp1< swizzle1 > w()const { return vecexp1< swizzle1 >(v); } + + MECANIM_FORCE_INLINE vecexp1< swizzle1 > x() { return vecexp1< swizzle1 >(v); } + MECANIM_FORCE_INLINE vecexp1< swizzle1 > y() { return vecexp1< swizzle1 >(v); } + MECANIM_FORCE_INLINE vecexp1< swizzle1 > z() { return vecexp1< swizzle1 >(v); } + MECANIM_FORCE_INLINE vecexp1< swizzle1 > w() { return vecexp1< swizzle1 >(v); } + + MECANIM_FORCE_INLINE vecexp4< swizzle > wxzy()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > xzwy()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > xwyz()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > wyxz()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > zywx()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > ywzx()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > yzxw()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > zxyw()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > zwxy()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > wwwz()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > wwzz()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > wzyx()const { return vecexp4< swizzle >(v); } + MECANIM_FORCE_INLINE vecexp4< swizzle > yxwz()const { return vecexp4< swizzle >(v); } + +protected: + packed_type v; +}; + +struct ATTRIBUTE_ALIGN(ALIGN4F) float4 : vecexp4 +{ + DEFINE_GET_TYPESTRING(float4) + + typedef vec4 value_type; + typedef vec4::scalar_type scalar_type; + typedef vec4::packed_type packed_type; + + MECANIM_FORCE_INLINE float4() {} + + MECANIM_FORCE_INLINE float4(float4 const& vector):vecexp4(vector.v) { } + + explicit MECANIM_FORCE_INLINE float4(scalar_type s):vecexp4(s) { } + + explicit MECANIM_FORCE_INLINE float4(packed_type const& vector):vecexp4(vector) { } + + template MECANIM_FORCE_INLINE float4(const vecexp4 &r):vecexp4(r) { } + + MECANIM_FORCE_INLINE float4(scalar_type x, scalar_type y, scalar_type z, scalar_type w):vecexp4(x,y,z,w) { } + + MECANIM_FORCE_INLINE float4(const float1 &x, const float1 &y, const float1 &z, const float1 &w):vecexp4(x,y,z,w) { } + + MECANIM_FORCE_INLINE float4 &operator=(const float4 &r) { vecexp4::operator =(r); return *this; } + + template MECANIM_FORCE_INLINE float4 &operator=(const vecexp4 &r) { vecexp4::operator =(r); return *this; } + template MECANIM_FORCE_INLINE float4 &operator=(const vecexp1 &r) { vecexp4::operator =(r); return *this; } + + template MECANIM_FORCE_INLINE float4 &operator+=(const vecexp4 &r) { value_type::v = Vadd(value_type::v, r.eval()); return *this; } + template MECANIM_FORCE_INLINE float4 &operator+=(const vecexp1 &r) { value_type::v = Vadd(value_type::v, r.eval()); return *this; } + MECANIM_FORCE_INLINE float4 &operator+=(float r) { value_type::v = Vadd(value_type::v, Vloadsf(r)); return *this; } + + template MECANIM_FORCE_INLINE float4 &operator-=(const vecexp4 &r) { value_type::v = Vsub(value_type::v, r.eval()); return *this; } + template MECANIM_FORCE_INLINE float4 &operator-=(const vecexp1 &r) { value_type::v = Vsub(value_type::v, r.eval()); return *this; } + MECANIM_FORCE_INLINE float4 &operator-=(float r) { value_type::v = Vsub(value_type::v, Vloadsf(r)); return *this; } + + template MECANIM_FORCE_INLINE float4 &operator*=(const vecexp4 &r) { value_type::v = Vmul(value_type::v, r.eval()); return *this; } + template MECANIM_FORCE_INLINE float4 &operator*=(const vecexp1 &r) { value_type::v = Vmul(value_type::v, r.eval()); return *this; } + MECANIM_FORCE_INLINE float4 &operator*=(float r) { value_type::v = Vmul(value_type::v, Vloadsf(r)); return *this; } + + + template MECANIM_FORCE_INLINE float4 &operator/=(const vecexp4 &r) { value_type::v = Vdiv(value_type::v, r.eval()); return *this; } + template MECANIM_FORCE_INLINE float4 &operator/=(const vecexp1 &r) { value_type::v = Vdiv(value_type::v, r.eval()); return *this; } + MECANIM_FORCE_INLINE float4 &operator/=(float r) { value_type::v = Vdiv(value_type::v, Vloadsf(r)); return *this; } + + // prefix decrement + MECANIM_FORCE_INLINE float4 &operator++() { value_type::v = Vinc(value_type::v); return *this; } + // postfix increment + MECANIM_FORCE_INLINE float4 operator++(int) { float4 r = *this; value_type::v = Vinc(value_type::eval() ); return r; } + + // prefix decrement + MECANIM_FORCE_INLINE float4 &operator--() { value_type::v = Vdec(value_type::v); return *this; } + // postfix decrement + MECANIM_FORCE_INLINE float4 operator--(int) { float4 r = *this; value_type::v = Vdec(value_type::eval() ); return r; } + + + static float4 zero() {return float4(Vzero()); } // 0 + static float4 one() {return float4(Vone());} // 1 + + + template + MECANIM_FORCE_INLINE void Transfer (TransferFunction& transfer) + { + /////@TODO: This is wrong. It will not work for SafeBinaryRead + /////// Probably other places in the code too! + + float ATTRIBUTE_ALIGN(ALIGN4F) buf[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + if(transfer.IsReading()) + { + transfer.Transfer(buf[0], "x"); + transfer.Transfer(buf[1], "y"); + transfer.Transfer(buf[2], "z"); + transfer.Transfer(buf[3], "w"); + + v = Vloadpf(buf, 0); + } + else if(transfer.IsWriting()) + { + Vstorepf(v, buf, 0); + + transfer.Transfer(buf[0], "x"); + transfer.Transfer(buf[1], "y"); + transfer.Transfer(buf[2], "z"); + transfer.Transfer(buf[3], "w"); + } + else + { + transfer.Transfer(buf[0], "x"); + transfer.Transfer(buf[1], "y"); + transfer.Transfer(buf[2], "z"); + transfer.Transfer(buf[3], "w"); + } + } +}; + +// vecexp4 Arithemtic +template static MECANIM_FORCE_INLINE vecexp4 operator+(const vecexp4 &l, const vecexp4 &r) +{ + return vecexp4( Vadd( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator+(const vecexp4 &l, const vecexp1 &r) +{ + return vecexp4( Vadd( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator+(const vecexp1 &l, const vecexp4 &r) +{ + return vecexp4( Vadd( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator-(const vecexp4 &l, const vecexp4 &r) +{ + return vecexp4( Vsub( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator-(const vecexp4 &l, const vecexp1 &r) +{ + return vecexp4( Vsub( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator-(const vecexp1 &l, const vecexp4 &r) +{ + return vecexp4( Vsub( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator*(const vecexp4 &l, const vecexp4 &r) +{ + return vecexp4( Vmul( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator*(const vecexp4 &l,const vecexp1 &r) +{ + return vecexp4( Vmul( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator*(const vecexp1 &l, const vecexp4 &r) +{ + return vecexp4( Vmul( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator/(const vecexp4 &l, const vecexp4 &r) +{ + return vecexp4( Vdiv( l.eval(), r.eval() )); +} +template static MECANIM_FORCE_INLINE vecexp4 operator/(const vecexp4 &l, const vecexp1 &r) +{ + return vecexp4( Vdiv( l.eval(), r.eval() )); +} + +template static MECANIM_FORCE_INLINE vecexp4 operator/(const vecexp1 &l, const vecexp4 &r) +{ + return vecexp4( Vdiv( l.eval(), r.eval() )); +} + + +// vecexp4 logic +template static MECANIM_FORCE_INLINE bool4 operator<(const vecexp4 &l, const vecexp4 &r) +{ + return bool4(Vcmplt(l.eval(), r.eval())); +} +template static MECANIM_FORCE_INLINE bool4 operator<(const vecexp4 &l, const float1 &r) +{ + return bool4(Vcmplt(l.eval(), r.eval())); +} +template static MECANIM_FORCE_INLINE bool4 operator<(const float1 &l, const vecexp4 &r) +{ + return bool4(Vcmplt(l.eval(), r.eval())); +} + +template static MECANIM_FORCE_INLINE bool4 operator<=(const vecexp4 &l, const vecexp4 &r) +{ + return bool4(Vcmple(l.eval(), r.eval())); +} +template static MECANIM_FORCE_INLINE bool4 operator<=(const vecexp4 &l, const float1 &r) +{ + return bool4(Vcmple(l.eval(), r.eval())); +} +template static MECANIM_FORCE_INLINE bool4 operator<=(const float1 &l, const vecexp4 &r) +{ + return bool4(Vcmple(l.eval(), r.eval())); +} + +template static MECANIM_FORCE_INLINE bool4 operator==(const vecexp4 &l, const vecexp4 &r) +{ + return bool4( Vcmpeq(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator==(const vecexp4 &l, const vecexp1 &r) +{ + return bool4( Vcmpeq(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator==(const vecexp1 &l, const vecexp4 &r) +{ + return bool4( Vcmpeq(l.eval(), r.eval()) ); +} + +template static MECANIM_FORCE_INLINE bool4 operator!=(const vecexp4 &l, const vecexp4 &r) +{ + return bool4( Vcmpneq(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator!=(const vecexp1 &l, const vecexp4 &r) +{ + return bool4( Vcmpneq(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator!=(const vecexp4 &l, const vecexp1 &r) +{ + return bool4( Vcmpneq(l.eval(), r.eval()) ); +} + +template static MECANIM_FORCE_INLINE bool4 operator>=(const vecexp4 &l, const vecexp4 &r) +{ + return bool4( Vcmpge(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator>=(const vecexp1 &l, const vecexp4 &r) +{ + return bool4( Vcmpge(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator>=(const vecexp4 &l, const vecexp1 &r) +{ + return bool4( Vcmpge(l.eval(), r.eval()) ); +} + +template static MECANIM_FORCE_INLINE bool4 operator>(const vecexp4 &l, const vecexp4 &r) +{ + return bool4( Vcmpgt(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator>(const vecexp4 &l, const vecexp1 &r) +{ + return bool4( Vcmpgt(l.eval(), r.eval()) ); +} +template static MECANIM_FORCE_INLINE bool4 operator>(const vecexp1 &l, const vecexp4 &r) +{ + return bool4( Vcmpgt(l.eval(), r.eval()) ); +} + +#define constant_float4(name, x,y,z,w) \ + cvec4f(c##name, x,y,z,w); \ + math::float4 const name(c##name); \ + +} + +#endif -- cgit v1.1-26-g67d0