diff --git a/glm/detail/_swizzle.hpp b/glm/detail/_swizzle.hpp index 0678982c01..e1f57ccb77 100644 --- a/glm/detail/_swizzle.hpp +++ b/glm/detail/_swizzle.hpp @@ -17,30 +17,25 @@ namespace detail char _buffer[1]; }; - template + template struct _swizzle_base1 : public _swizzle_base0 { }; - template - struct _swizzle_base1 : public _swizzle_base0 - { - }; - - template - struct _swizzle_base1<2, T, Q, E0,E1,-1,-2, false> : public _swizzle_base0 + template + struct _swizzle_base1<2, T, Q, E0,E1,-1,-2, Aligned> : public _swizzle_base0 { GLM_FUNC_QUALIFIER vec<2, T, Q> operator ()() const { return vec<2, T, Q>(this->elem(E0), this->elem(E1)); } }; - template - struct _swizzle_base1<3, T, Q, E0,E1,E2,3, false> : public _swizzle_base0 + template + struct _swizzle_base1<3, T, Q, E0,E1,E2,-1, Aligned> : public _swizzle_base0 { GLM_FUNC_QUALIFIER vec<3, T, Q> operator ()() const { return vec<3, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2)); } }; - template - struct _swizzle_base1<4, T, Q, E0,E1,E2,E3, false> : public _swizzle_base0 + template + struct _swizzle_base1<4, T, Q, E0,E1,E2,E3, Aligned> : public _swizzle_base0 { GLM_FUNC_QUALIFIER vec<4, T, Q> operator ()() const { return vec<4, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); } }; @@ -355,33 +350,33 @@ namespace glm struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; }; #define GLM_SWIZZLE3_3_MEMBERS(T, Q ,E0,E1,E2) \ - struct { detail::_swizzle<3, T, Q, 0,0,0,3> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 0,0,1,3> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 0,0,2,3> E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 0,1,0,3> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 0,1,1,3> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 0,1,2,3> E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 0,2,0,3> E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 0,2,1,3> E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 0,2,2,3> E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 1,0,0,3> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 1,0,1,3> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 1,0,2,3> E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 1,1,0,3> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 1,1,1,3> E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 1,1,2,3> E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 1,2,0,3> E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 1,2,1,3> E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 1,2,2,3> E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 2,0,0,3> E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 2,0,1,3> E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 2,0,2,3> E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 2,1,0,3> E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 2,1,1,3> E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 2,1,2,3> E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 2,2,0,3> E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 2,2,1,3> E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 2,2,2,3> E2 ## E2 ## E2; }; + struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; }; #define GLM_SWIZZLE3_4_MEMBERS(T, Q, E0,E1,E2) \ struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ @@ -485,70 +480,70 @@ namespace glm struct { detail::_swizzle<2,T, Q, 3,3,-1,-2> E3 ## E3; }; #define GLM_SWIZZLE4_3_MEMBERS(T, Q, E0,E1,E2,E3) \ - struct { detail::_swizzle<3, T, Q, 0,0,0,3> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 0,0,1,3> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 0,0,2,3> E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 0,0,3,3> E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 0,1,0,3> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 0,1,1,3> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 0,1,2,3> E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 0,1,3,3> E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 0,2,0,3> E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 0,2,1,3> E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 0,2,2,3> E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 0,2,3,3> E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 0,3,0,3> E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 0,3,1,3> E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 0,3,2,3> E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 0,3,3,3> E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 1,0,0,3> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 1,0,1,3> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 1,0,2,3> E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 1,0,3,3> E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 1,1,0,3> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 1,1,1,3> E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 1,1,2,3> E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 1,1,3,3> E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 1,2,0,3> E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 1,2,1,3> E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 1,2,2,3> E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 1,2,3,3> E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 1,3,0,3> E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 1,3,1,3> E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 1,3,2,3> E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 1,3,3,3> E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 2,0,0,3> E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 2,0,1,3> E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 2,0,2,3> E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 2,0,3,3> E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 2,1,0,3> E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 2,1,1,3> E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 2,1,2,3> E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 2,1,3,3> E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 2,2,0,3> E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 2,2,1,3> E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 2,2,2,3> E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 2,2,3,3> E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 2,3,0,3> E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 2,3,1,3> E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 2,3,2,3> E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 2,3,3,3> E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 3,0,0,3> E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 3,0,1,3> E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 3,0,2,3> E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 3,0,3,3> E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 3,1,0,3> E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 3,1,1,3> E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 3,1,2,3> E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 3,1,3,3> E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 3,2,0,3> E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 3,2,1,3> E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 3,2,2,3> E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 3,2,3,3> E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, Q, 3,3,0,3> E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, Q, 3,3,1,3> E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, Q, 3,3,2,3> E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, Q, 3,3,3,3> E3 ## E3 ## E3; }; + struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,0,3,-1> E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,1,3,-1> E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,2,3,-1> E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,0,-1> E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,1,-1> E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,2,-1> E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 0,3,3,-1> E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,0,3,-1> E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,1,3,-1> E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,2,3,-1> E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,0,-1> E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,1,-1> E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,2,-1> E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 1,3,3,-1> E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,0,3,-1> E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,1,3,-1> E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,2,3,-1> E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,0,-1> E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,1,-1> E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,2,-1> E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 2,3,3,-1> E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,0,-1> E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,1,-1> E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,2,-1> E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,0,3,-1> E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,0,-1> E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,1,-1> E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,2,-1> E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,1,3,-1> E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,0,-1> E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,1,-1> E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,2,-1> E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,2,3,-1> E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,0,-1> E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,1,-1> E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,2,-1> E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<3, T, Q, 3,3,3,-1> E3 ## E3 ## E3; }; #define GLM_SWIZZLE4_4_MEMBERS(T, Q, E0,E1,E2,E3) \ struct { detail::_swizzle<4, T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ diff --git a/glm/detail/_vectorize.hpp b/glm/detail/_vectorize.hpp index 807b1b1de6..1fcaec3152 100644 --- a/glm/detail/_vectorize.hpp +++ b/glm/detail/_vectorize.hpp @@ -52,12 +52,6 @@ namespace detail { return vec<1, T, Q>(Func(a.x, b.x)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, T, Q> call(Fct Func, vec<1, T, Q> const& a, vec<1, T, Q> const& b) - { - return vec<1, T, Q>(Func(a.x, b.x)); - } }; template class vec, typename T, qualifier Q> @@ -67,12 +61,6 @@ namespace detail { return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, T, Q> call(Fct Func, vec<2, T, Q> const& a, vec<2, T, Q> const& b) - { - return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y)); - } }; template class vec, typename T, qualifier Q> @@ -82,12 +70,6 @@ namespace detail { return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(Fct Func, vec<3, T, Q> const& a, vec<3, T, Q> const& b) - { - return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); - } }; template class vec, typename T, qualifier Q> @@ -97,12 +79,6 @@ namespace detail { return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(Fct Func, vec<4, T, Q> const& a, vec<4, T, Q> const& b) - { - return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); - } }; template class vec, length_t L, typename T, qualifier Q> @@ -115,11 +91,6 @@ namespace detail { return vec<1, T, Q>(Func(a.x, b)); } - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, T, Q> call(Fct Func, vec<1, T, Q> const& a, T b) - { - return vec<1, T, Q>(Func(a.x, b)); - } }; template class vec, typename T, qualifier Q> @@ -129,12 +100,6 @@ namespace detail { return vec<2, T, Q>(Func(a.x, b), Func(a.y, b)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, T, Q> call(Fct Func, vec<2, T, Q> const& a, T b) - { - return vec<2, T, Q>(Func(a.x, b), Func(a.y, b)); - } }; template class vec, typename T, qualifier Q> @@ -144,12 +109,6 @@ namespace detail { return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(Fct Func, vec<3, T, Q> const& a, T b) - { - return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b)); - } }; template class vec, typename T, qualifier Q> @@ -159,11 +118,6 @@ namespace detail { return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b)); } - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(Fct Func, vec<4, T, Q> const& a, T b) - { - return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b)); - } }; template @@ -176,12 +130,6 @@ namespace detail { return vec<1, int, Q>(Func(a.x, b.x)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, int, Q> call(Fct Func, vec<1, T, Q> const& a, vec<1, int, Q> const& b) - { - return vec<1, int, Q>(Func(a.x, b.x)); - } }; template @@ -191,11 +139,6 @@ namespace detail { return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y)); } - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, int, Q> call(Fct Func, vec<2, T, Q> const& a, vec<2, int, Q> const& b) - { - return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y)); - } }; template @@ -205,11 +148,6 @@ namespace detail { return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); } - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, int, Q> call(Fct Func, vec<3, T, Q> const& a, vec<3, int, Q> const& b) - { - return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); - } }; template @@ -219,12 +157,6 @@ namespace detail { return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, int, Q> call(Fct Func, vec<4, T, Q> const& a, vec<4, int, Q> const& b) - { - return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); - } }; }//namespace detail }//namespace glm diff --git a/glm/detail/func_common.inl b/glm/detail/func_common.inl index 049b6e7724..f8584c9e87 100644 --- a/glm/detail/func_common.inl +++ b/glm/detail/func_common.inl @@ -20,11 +20,6 @@ namespace glm return (y < x) ? y : x; } - template - struct TMin { - T operator()(const T& a, const T& b) { return min(a, b); } - }; - // max template GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType max(genType x, genType y) @@ -34,11 +29,6 @@ namespace glm return (x < y) ? y : x; } - template - struct TMax { - T operator()(const T& a, const T& b) { return max(a, b); } - }; - // abs template<> GLM_FUNC_QUALIFIER GLM_CONSTEXPR int abs(int x) @@ -47,11 +37,6 @@ namespace glm return (x ^ y) - y; } - template - struct TAbs { - T operator()(const T& a) { return abs(a); } - }; - // round # if GLM_HAS_CXX11_STL using ::std::round; @@ -65,11 +50,6 @@ namespace glm } # endif - template - struct TRound { - T operator()(const T& a) { return round(a); } - }; - // trunc # if GLM_HAS_CXX11_STL using ::std::trunc; @@ -83,16 +63,6 @@ namespace glm } # endif - template - struct TTrunc { - T operator()(const T& a) { return trunc(a); } - }; - - template - struct TFmod { - T operator()(const T& a, const T& b) { return std::fmod(a, b); } - }; - }//namespace glm namespace glm{ @@ -110,7 +80,7 @@ namespace detail template struct compute_mix_vector { - GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, vec const& a) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x, vec const& y, vec const& a) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); @@ -121,7 +91,7 @@ namespace detail template struct compute_mix_vector { - GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, vec const& a) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x, vec const& y, vec const& a) { vec Result(0); for(length_t i = 0; i < x.length(); ++i) @@ -133,7 +103,7 @@ namespace detail template struct compute_mix_scalar { - GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, U const& a) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x, vec const& y, U const& a) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); @@ -144,7 +114,7 @@ namespace detail template struct compute_mix_scalar { - GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y, bool const& a) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x, vec const& y, bool const& a) { return a ? y : x; } @@ -153,7 +123,7 @@ namespace detail template struct compute_mix { - GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, U const& a) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, U const& a) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a"); @@ -164,7 +134,7 @@ namespace detail template struct compute_mix { - GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, bool const& a) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, bool const& a) { return a ? y : x; } @@ -173,7 +143,7 @@ namespace detail template struct compute_sign { - GLM_FUNC_QUALIFIER static vec call(vec const& x) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x) { return vec(glm::lessThan(vec(0), x)) - vec(glm::lessThan(x, vec(0))); } @@ -183,7 +153,7 @@ namespace detail template struct compute_sign { - GLM_FUNC_QUALIFIER static vec call(vec const& x) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& x) { T const Shift(static_cast(sizeof(T) * 8 - 1)); vec const y(vec::type, Q>(-x) >> typename detail::make_unsigned::type(Shift)); @@ -248,21 +218,12 @@ namespace detail } }; - template - struct compute_fma - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b, vec const& c) - { - return a * b + c; - } - }; - template struct compute_min_vector { GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y) { - return detail::functor2::call(TMin(), x, y); + return detail::functor2::call(min, x, y); } }; @@ -271,7 +232,7 @@ namespace detail { GLM_FUNC_QUALIFIER static vec call(vec const& x, vec const& y) { - return detail::functor2::call(TMax(), x, y); + return detail::functor2::call(max, x, y); } }; @@ -303,56 +264,6 @@ namespace detail return tmp * tmp * (static_cast(3) - static_cast(2) * tmp); } }; - - template - struct convert_vec3_to_vec4W0 - { - GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a) - { - return vec<4, T, Q>(a.x, a.y, a.z, 0.0f); - } - }; - - template - struct convert_vec3_to_vec4WZ - { - GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a) - { - return vec<4, T, Q>(a.x, a.y, a.z, a.z); - } - }; - - template - struct convert_vec3_to_vec4W1 - { - GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a) - { - return vec<4, T, Q>(a.x, a.y, a.z, 1.0f); - } - }; - - template - struct convert_vec4_to_vec3 - { - GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a) - { - return vec<4, T, Q>(a.x, a.y, a.z, 0.0f); - } - }; - - template - struct convert_splat { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec v; - for (int i = 0; i < L; ++i) - v[i] = a[c]; - return v; - } - }; - - }//namespace detail template @@ -511,61 +422,6 @@ namespace detail return detail::compute_mod::value>::call(x, y); } - template - GLM_FUNC_QUALIFIER vec fma(vec const& a, vec const& b, vec const& c) - { - return detail::compute_fma::value>::call(a, b, c); - } - - template - GLM_FUNC_QUALIFIER vec<4, T, Q> xyz0(vec<3, T, Q> const& a) - { - return detail::convert_vec3_to_vec4W0::value>::call(a); - } - - template - GLM_FUNC_QUALIFIER vec<4, T, Q> xyz1(vec<3, T, Q> const& a) - { - return detail::convert_vec3_to_vec4W1::value>::call(a); - } - - template - GLM_FUNC_QUALIFIER vec<4, T, Q> xyzz(vec<3, T, Q> const& a) - { - return detail::convert_vec3_to_vec4WZ::value>::call(a); - } - - template - GLM_FUNC_QUALIFIER vec<3, T, Q> xyz(vec<4, T, Q> const& a) - { - return detail::convert_vec4_to_vec3::value>::call(a); - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec splatX(vec const& a) - { - return detail::convert_splat::value>::template call<0>(a); - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec splatY(vec const& a) - { - return detail::convert_splat::value>::template call<1>(a); - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec splatZ(vec const& a) - { - return detail::convert_splat::value>::template call<2>(a); - } - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec splatW(vec const& a) - { - return detail::convert_splat::value>::template call<3>(a); - } - - // modf template GLM_FUNC_QUALIFIER genType modf(genType x, genType & i) diff --git a/glm/detail/func_common_simd.inl b/glm/detail/func_common_simd.inl index 55c72286e4..ce0032d33f 100644 --- a/glm/detail/func_common_simd.inl +++ b/glm/detail/func_common_simd.inl @@ -225,389 +225,7 @@ namespace detail return Result; } }; - - template - struct compute_fma<4, float, Q, true> - { - GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b, vec<4, float, Q> const& c) - { - vec<4, float, Q> Result; - Result.data = glm_vec4_fma(a.data, b.data, c.data); - return Result; - } - }; - - template - struct compute_fma<3, float, Q, true> - { - GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b, vec<3, float, Q> const& c) - { - vec<3, float, Q> Result; - Result.data = glm_vec4_fma(a.data, b.data, c.data); - return Result; - } - }; - - - template - struct compute_fma<4, double, Q, true> - { - GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b, vec<4, double, Q> const& c) - { - vec<4, double, Q> Result; -# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG) - Result.data = _mm256_fmadd_pd(a.data, b.data, c.data); -# elif (GLM_ARCH & GLM_ARCH_AVX_BIT) - Result.data = _mm256_add_pd(_mm256_mul_pd(a.data, b.data), c.data); -# else - Result.data.setv(0, _mm_add_pd(_mm_mul_pd(a.data.getv(0), b.data.getv(0)), c.data.getv(0))); - Result.data.setv(1, _mm_add_pd(_mm_mul_pd(a.data.getv(1), b.data.getv(1)), c.data.getv(1))); -# endif - return Result; - } - }; - - // copy vec3 to vec4 and set w to 0 - template - struct convert_vec3_to_vec4W0 - { - GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a) - { - vec<4, float, Q> v; -#if (GLM_ARCH & GLM_ARCH_SSE41_BIT) - v.data = _mm_blend_ps(a.data, _mm_setzero_ps(), 8); -#else - __m128i mask = _mm_set_epi32(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); - __m128 v0 = _mm_castsi128_ps(_mm_and_si128(_mm_castps_si128(a.data), mask)); - v.data = v0; -#endif - return v; - } - }; - - // copy vec3 to vec4 and set w to 1 - template - struct convert_vec3_to_vec4W1 - { - GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a) - { - vec<4, float, Q> v; -#if (GLM_ARCH & GLM_ARCH_SSE41_BIT) - v.data = _mm_blend_ps(a.data, _mm_set1_ps(1.0f), 8); -#else - __m128 t1 = _mm_shuffle_ps(a.data, a.data, _MM_SHUFFLE(0, 2, 1, 3)); //permute x, w - __m128 t2 = _mm_move_ss(t1, _mm_set_ss(1.0f)); // set x to 1.0f - v.data = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(0, 2, 1, 3)); //permute x, w -#endif - return v; - } - }; - - // copy vec3 to vec4 and set w to vec3.z - template - struct convert_vec3_to_vec4WZ - { - GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a) - { - vec<4, float, Q> v; - v.data = _mm_shuffle_ps(a.data, a.data, _MM_SHUFFLE(2, 2, 1, 0)); - return v; - } - }; - - // copy vec3 to vec4 and set w to 0 - template - struct convert_vec3_to_vec4W0 - { - GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a) - { - vec<4, double, Q> v; -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - v.data = _mm256_blend_pd(a.data, _mm256_setzero_pd(), 8); -#else - v.data.setv(0, a.data.getv(0)); - glm_dvec2 av2 = a.data.getv(1); - av2 = _mm_shuffle_pd(av2, _mm_setzero_pd(), 2); - v.data.setv(1, av2); -#endif - return v; - } - }; - - // copy vec3 to vec4 and set w to vec3.z - template - struct convert_vec3_to_vec4WZ - { - GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a) - { - vec<4, double, Q> v; -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - v.data = _mm256_permute_pd(a.data, 2); -#else - v.data.setv(0, a.data.getv(0)); - glm_dvec2 av2 = a.data.getv(1); - __m128d t1 = _mm_shuffle_pd(av2, av2, 0); - v.data.setv(1, t1); -#endif - return v; - } - }; - - // copy vec3 to vec4 and set w to 1 - template - struct convert_vec3_to_vec4W1 - { - GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a) - { - vec<4, double, Q> v; -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - v.data = _mm256_blend_pd(a.data, _mm256_set1_pd(1.0), 8); -#else - v.data.setv(0, a.data.getv(0)); - glm_dvec2 av2 = a.data.getv(1); - av2 = _mm_shuffle_pd(av2, _mm_set1_pd(1.), 2); - v.data.setv(1, av2); -#endif - return v; - } - }; - - template - struct convert_vec4_to_vec3 { - GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<4, float, Q> const& a) - { - vec<3, float, Q> v; - v.data = a.data; - return v; - } - }; - - template - struct convert_vec4_to_vec3 { - GLM_FUNC_QUALIFIER static vec<3, double, Q> call(vec<4, double, Q> const& a) - { - vec<3, double, Q> v; -#if GLM_ARCH & GLM_ARCH_AVX_BIT - v.data = a.data; -#else - v.data.setv(0, a.data.getv(0)); - v.data.setv(1, a.data.getv(1)); -#endif - return v; - } - }; - - - // set all coordinates to same value vec[c] - template - struct convert_splat { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec Result; - const int s = _MM_SHUFFLE(c, c, c, c); - glm_f32vec4 va = static_cast(a.data); -# if GLM_ARCH & GLM_ARCH_AVX_BIT - Result.data = _mm_permute_ps(va, s); -# else - Result.data = _mm_shuffle_ps(va, va, s); -# endif - return Result; - } - }; - - // set all coordinates to same value vec[c] - template - struct convert_splat { - - template - struct detailSSE - {}; - - template - struct detailSSE - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec Result; - glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(0), a.data.getv(0), c | c << 1); - Result.data.setv(0, r0); - Result.data.setv(1, r0); - return Result; - } - }; - - template - struct detailSSE - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec Result; - const unsigned int d = static_cast(c - 2); - glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(1), a.data.getv(1), d | d << 1); - Result.data.setv(0, r0); - Result.data.setv(1, r0); - return Result; - } - }; - -#if GLM_ARCH & GLM_ARCH_AVX_BIT - template //note: bool is useless but needed to compil on linux (gcc) - struct detailAVX - {}; - - template - struct detailAVX - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec Result; - __m256d t1 = _mm256_permute2f128_pd(a.data, a.data, 0x0); - Result.data = _mm256_permute_pd(t1, 0); - return Result; - } - }; - - template - struct detailAVX - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec Result; - __m256d t1 = _mm256_permute2f128_pd(a.data, a.data, 0x0); - Result.data = _mm256_permute_pd(t1, 0xf); - return Result; - } - }; - - template - struct detailAVX - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec Result; - __m256d t2 = _mm256_permute2f128_pd(a.data, a.data, 0x11); - Result.data = _mm256_permute_pd(t2, 0x0); - return Result; - } - }; - - template - struct detailAVX - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - vec Result; - __m256d t2 = _mm256_permute2f128_pd(a.data, a.data, 0x11); - Result.data = _mm256_permute_pd(t2, 0xf); - return Result; - } - }; -#endif //GLM_ARCH & GLM_ARCH_AVX_BIT - - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - { - //return compute_splat::call(a); - vec Result; -# if GLM_ARCH & GLM_ARCH_AVX2_BIT - Result.data = _mm256_permute4x64_pd(a.data, _MM_SHUFFLE(c, c, c, c)); -# elif GLM_ARCH & GLM_ARCH_AVX_BIT - Result = detailAVX::call(a); -# else -#if 1 //detail<(c <= 1), c>::call2(a) is equivalent to following code but without if constexpr usage - Result = detailSSE<(c <= 1), c>::call(a); -#else - if constexpr (c <= 1) - { - glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(0), a.data.getv(0), c | c << 1); - Result.data.setv(0, r0); - Result.data.setv(1, r0); - } - else - { - const unsigned int d = (unsigned int)(c - 2); - glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(1), a.data.getv(1), d | d << 1); - Result.data.setv(0, r0); - Result.data.setv(1, r0); - } -#endif -# endif - return Result; - } - }; - - }//namespace detail }//namespace glm #endif//GLM_ARCH & GLM_ARCH_SSE2_BIT - -#if GLM_ARCH & GLM_ARCH_NEON_BIT -namespace glm { - namespace detail { - - template - struct convert_vec3_to_vec4W0 - { - GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a) - { - vec<4, float, Q> v; - static const uint32x4_t mask = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - v.data = vbslq_f32(mask, a.data, vdupq_n_f32(0)); - return v; - } - }; - - template - struct convert_vec4_to_vec3 { - GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<4, float, Q> const& a) - { - vec<3, float, Q> v; - v.data = a.data; - return v; - } - }; - - template - struct compute_splat { - template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call(vec const& a) - {} - - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call<0>(vec const& a) - { - vec Result; - Result.data = vdupq_lane_f32(vget_low_f32(a.data), 0); - return Result; - } - - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call<1>(vec const& a) - { - vec Result; - Result.data = vdupq_lane_f32(vget_low_f32(a.data), 1); - return Result; - } - - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call<2>(vec const& a) - { - vec Result; - Result.data = vdupq_lane_f32(vget_high_f32(a.data), 0); - return Result; - } - - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec call<3>(vec const& a) - { - vec Result; - Result.data = vdupq_lane_f32(vget_high_f32(a.data), 1); - return Result; - } - }; - -}//namespace detail -}//namespace glm -#endif //GLM_ARCH & GLM_ARCH_NEON_BIT diff --git a/glm/detail/func_geometric.inl b/glm/detail/func_geometric.inl index 8f3cc7734c..404c99056a 100644 --- a/glm/detail/func_geometric.inl +++ b/glm/detail/func_geometric.inl @@ -59,13 +59,8 @@ namespace detail { GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) { - // VS 17.7.4 generates longer assembly (~20 instructions vs 11 instructions) - #if defined(_MSC_VER) - return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; - #else - vec<4, T, Q> tmp(a * b); - return (tmp.x + tmp.y) + (tmp.z + tmp.w); - #endif + vec<4, T, Q> tmp(a * b); + return (tmp.x + tmp.y) + (tmp.z + tmp.w); } }; @@ -81,17 +76,6 @@ namespace detail x.z * y.x - y.z * x.x, x.x * y.y - y.x * x.y); } - - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& x, vec<4, T, Q> const& y) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'cross' accepts only floating-point inputs"); - - return vec<4, T, Q>( - x.y * y.z - y.y * x.z, - x.z * y.x - y.z * x.x, - x.x * y.y - y.x * x.y, - 0.0f); - } }; template diff --git a/glm/detail/func_geometric_simd.inl b/glm/detail/func_geometric_simd.inl index 4c7f56bf6f..2076dae055 100644 --- a/glm/detail/func_geometric_simd.inl +++ b/glm/detail/func_geometric_simd.inl @@ -35,36 +35,18 @@ namespace detail } }; - template - struct compute_dot, float, true> - { - GLM_FUNC_QUALIFIER static float call(vec<3, float, Q> const& a, vec<3, float, Q> const& b) - { - vec<4, float, Q> aa = xyz0(a); - vec<4, float, Q> bb = xyz0(b); - return _mm_cvtss_f32(glm_vec1_dot(aa.data, bb.data)); - } - }; - template struct compute_cross { GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b) { - vec<4, float, Q> aa = xyzz(a); - vec<4, float, Q> bb = xyzz(b); - __m128 const xpd0 = glm_vec4_cross(aa.data, bb.data); + __m128 const set0 = _mm_set_ps(0.0f, a.z, a.y, a.x); + __m128 const set1 = _mm_set_ps(0.0f, b.z, b.y, b.x); + __m128 const xpd0 = glm_vec4_cross(set0, set1); - vec<3, float, Q> Result; - Result.data = xpd0; - return Result; - } - - GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) - { vec<4, float, Q> Result; - Result.data = glm_vec4_cross(a.data, b.data); - return Result; + Result.data = xpd0; + return vec<3, float, Q>(Result); } }; diff --git a/glm/detail/func_matrix.inl b/glm/detail/func_matrix.inl index 9c7f7eb765..081761f35b 100644 --- a/glm/detail/func_matrix.inl +++ b/glm/detail/func_matrix.inl @@ -318,69 +318,28 @@ namespace detail } }; - template - struct inv3x3 {}; - - template - struct inv3x3 - { - GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m) - { - // see: https://www.onlinemathstutor.org/post/3x3_inverses - - vec<4, T, Q> a = xyz0(m[0]); - vec<4, T, Q> b = xyz0(m[1]); - vec<4, T, Q> c = xyz0(m[2]); - - vec<4, T, Q> i0 = compute_cross::call(b, c); - vec<4, T, Q> i1 = compute_cross::call(c, a); - vec<4, T, Q> i2 = compute_cross::call(a, b); - - mat<3, 3, T, Q> Inverse; - Inverse[0] = xyz(i0); - Inverse[1] = xyz(i1); - Inverse[2] = xyz(i2); - Inverse = transpose(Inverse); - - T Determinant = compute_dot, T, true>::call(a, compute_cross::call(b, c)); - vec<3, T, Q> OneOverDeterminant(static_cast(1) / Determinant); - Inverse *= OneOverDeterminant; - return Inverse; - } - }; - - template - struct inv3x3 + template + struct compute_inverse<3, 3, T, Q, Aligned> { GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m) { T OneOverDeterminant = static_cast(1) / ( - +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) + + m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2])); mat<3, 3, T, Q> Inverse; - Inverse[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]); - Inverse[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]); - Inverse[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]); - Inverse[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]); - Inverse[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]); - Inverse[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]); - Inverse[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]); - Inverse[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]); - Inverse[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]); - - Inverse *= OneOverDeterminant; - return Inverse; - } - }; + Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDeterminant; + Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDeterminant; + Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDeterminant; + Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDeterminant; + Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDeterminant; + Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDeterminant; + Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDeterminant; + Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDeterminant; + Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDeterminant; - template - struct compute_inverse<3, 3, T, Q, Aligned> - { - GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m) - { - return detail::inv3x3::value>::call(m); + return Inverse; } }; diff --git a/glm/detail/func_matrix_simd.inl b/glm/detail/func_matrix_simd.inl index 9e47bf707a..b9bb4615de 100644 --- a/glm/detail/func_matrix_simd.inl +++ b/glm/detail/func_matrix_simd.inl @@ -37,17 +37,6 @@ namespace detail } }; - template - struct compute_transpose<3, 3, float, Q, true> - { - GLM_FUNC_QUALIFIER static mat<3, 3, float, Q> call(mat<3, 3, float, Q> const& m) - { - mat<3, 3, float, Q> Result; - glm_mat3_transpose(&m[0].data, &Result[0].data); - return Result; - } - }; - template struct compute_determinant<4, 4, float, Q, true> { diff --git a/glm/detail/qualifier.hpp b/glm/detail/qualifier.hpp index cb4e108a7a..a6c96cca5c 100644 --- a/glm/detail/qualifier.hpp +++ b/glm/detail/qualifier.hpp @@ -126,24 +126,6 @@ namespace detail typedef glm_u32vec4 type; }; - template<> - struct storage<3, float, true> - { - typedef glm_f32vec4 type; - }; - - template<> - struct storage<3, int, true> - { - typedef glm_i32vec4 type; - }; - - template<> - struct storage<3, unsigned int, true> - { - typedef glm_i32vec4 type; - }; - template<> struct storage<2, double, true> { @@ -161,38 +143,13 @@ namespace detail { typedef glm_u64vec2 type; }; - - - template<> - struct storage<3, detail::uint64, true> - { - typedef glm_u64vec2 type; - }; - +# endif +# if (GLM_ARCH & GLM_ARCH_AVX_BIT) template<> struct storage<4, double, true> { -# if (GLM_ARCH & GLM_ARCH_AVX_BIT) typedef glm_f64vec4 type; -# else - struct type - { - glm_f64vec2 data[2]; - GLM_CONSTEXPR glm_f64vec2 getv(int i) const { - return data[i]; - } - GLM_CONSTEXPR void setv(int i, const glm_f64vec2& v) { - data[i] = v; - } - }; -# endif }; - - - template<> - struct storage<3, double, true> : public storage<4, double, true> - {}; - # endif # if (GLM_ARCH & GLM_ARCH_AVX2_BIT) @@ -216,38 +173,17 @@ namespace detail typedef glm_f32vec4 type; }; - template<> - struct storage<3, float, true> : public storage<4, float, true> - {}; - template<> struct storage<4, int, true> { typedef glm_i32vec4 type; }; - template<> - struct storage<3, int, true> : public storage<4, int, true> - {}; - template<> struct storage<4, unsigned int, true> { typedef glm_u32vec4 type; }; - - template<> - struct storage<3, unsigned int, true> : public storage<4, unsigned int, true> - {}; - - template<> - struct storage<3, double, true> - { - typedef struct alignas(4 * sizeof(double)) type { - double data[4]; - } type; - }; - # endif enum genTypeEnum diff --git a/glm/detail/type_mat3x3.inl b/glm/detail/type_mat3x3.inl index 5ccfb22932..a9b633ae2b 100644 --- a/glm/detail/type_mat3x3.inl +++ b/glm/detail/type_mat3x3.inl @@ -1,5 +1,4 @@ #include "../matrix.hpp" -#include "../common.hpp" namespace glm { @@ -308,10 +307,9 @@ namespace glm template GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(U s) { - col_type sv(s); - this->value[0] *= sv; - this->value[1] *= sv; - this->value[2] *= sv; + this->value[0] *= s; + this->value[1] *= s; + this->value[2] *= s; return *this; } @@ -470,86 +468,54 @@ namespace glm GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v) { return typename mat<3, 3, T, Q>::col_type( - m[0] * splatX(v) + m[1] * splatY(v) + m[2] * splatZ(v)); + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m) { return typename mat<3, 3, T, Q>::row_type( - dot(m[0], v), - dot(m[1], v), - dot(m[2], v)); - } - - namespace detail - { - template - struct mul3x3 {}; - -#if GLM_CONFIG_SIMD == GLM_ENABLE - template - struct mul3x3 - { - GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) - { - typename mat<4, 4, T, Q>::col_type const SrcA0 = xyzz(m1[0]); - typename mat<4, 4, T, Q>::col_type const SrcA1 = xyzz(m1[1]); - typename mat<4, 4, T, Q>::col_type const SrcA2 = xyzz(m1[2]); - - typename mat<4, 4, T, Q>::col_type const SrcB0 = xyzz(m2[0]); - typename mat<4, 4, T, Q>::col_type const SrcB1 = xyzz(m2[1]); - typename mat<4, 4, T, Q>::col_type const SrcB2 = xyzz(m2[2]); - - mat<3, 3, T, Q> Result; - Result[0] = xyz(glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0)))); - Result[1] = xyz(glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1)))); - Result[2] = xyz(glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2)))); - return mat<3, 3, T, Q>(Result); - } - }; -#endif - template - struct mul3x3 - { - GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) - { - typename mat<3, 3, T, Q>::col_type const& SrcA0 = m1[0]; - typename mat<3, 3, T, Q>::col_type const& SrcA1 = m1[1]; - typename mat<3, 3, T, Q>::col_type const& SrcA2 = m1[2]; - - typename mat<3, 3, T, Q>::col_type const& SrcB0 = m2[0]; - typename mat<3, 3, T, Q>::col_type const& SrcB1 = m2[1]; - typename mat<3, 3, T, Q>::col_type const& SrcB2 = m2[2]; - - mat<3, 3, T, Q> Result; - // note: the following lines are decomposed to have consistent results between simd and non simd code (prevent rounding error because of operation order) - //Result[0] = SrcA2 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x; - //Result[1] = SrcA2 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x; - //Result[2] = SrcA2 * SrcB2.z + SrcA1 * SrcB2.y + SrcA0 * SrcB2.x; - - typename mat<3, 3, T, Q>::col_type tmp; - tmp = SrcA0 * SrcB0.x; - tmp += SrcA1 * SrcB0.y; - tmp += SrcA2 * SrcB0.z; - Result[0] = tmp; - tmp = SrcA0 * SrcB1.x; - tmp += SrcA1 * SrcB1.y; - tmp += SrcA2 * SrcB1.z; - Result[1] = tmp; - tmp = SrcA0 * SrcB2.x; - tmp += SrcA1 * SrcB2.y; - tmp += SrcA2 * SrcB2.z; - Result[2] = tmp; - return Result; - } - }; + m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z, + m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z, + m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2) { - return detail::mul3x3::value>::call(m1, m2); + T const SrcA00 = m1[0][0]; + T const SrcA01 = m1[0][1]; + T const SrcA02 = m1[0][2]; + T const SrcA10 = m1[1][0]; + T const SrcA11 = m1[1][1]; + T const SrcA12 = m1[1][2]; + T const SrcA20 = m1[2][0]; + T const SrcA21 = m1[2][1]; + T const SrcA22 = m1[2][2]; + + T const SrcB00 = m2[0][0]; + T const SrcB01 = m2[0][1]; + T const SrcB02 = m2[0][2]; + T const SrcB10 = m2[1][0]; + T const SrcB11 = m2[1][1]; + T const SrcB12 = m2[1][2]; + T const SrcB20 = m2[2][0]; + T const SrcB21 = m2[2][1]; + T const SrcB22 = m2[2][2]; + + mat<3, 3, T, Q> Result; + Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02; + Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02; + Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02; + Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12; + Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12; + Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12; + Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22; + Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22; + Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22; + return Result; } template diff --git a/glm/detail/type_mat4x4.inl b/glm/detail/type_mat4x4.inl index 6e328a9e44..116731d747 100644 --- a/glm/detail/type_mat4x4.inl +++ b/glm/detail/type_mat4x4.inl @@ -1,5 +1,4 @@ #include "../matrix.hpp" -#include "../geometric.hpp" namespace glm { @@ -589,10 +588,10 @@ namespace glm ) { return typename mat<4, 4, T, Q>::row_type( - glm::dot(m[0], v), - glm::dot(m[1], v), - glm::dot(m[2], v), - glm::dot(m[3], v)); + m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3], + m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3], + m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3], + m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]); } template @@ -627,89 +626,25 @@ namespace glm m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]); } - namespace detail - { - template - struct mul4x4 {}; - - template - struct mul4x4 - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) - { - typename mat<4, 4, T, Q>::col_type const SrcA0 = m1[0]; - typename mat<4, 4, T, Q>::col_type const SrcA1 = m1[1]; - typename mat<4, 4, T, Q>::col_type const SrcA2 = m1[2]; - typename mat<4, 4, T, Q>::col_type const SrcA3 = m1[3]; - - typename mat<4, 4, T, Q>::col_type const SrcB0 = m2[0]; - typename mat<4, 4, T, Q>::col_type const SrcB1 = m2[1]; - typename mat<4, 4, T, Q>::col_type const SrcB2 = m2[2]; - typename mat<4, 4, T, Q>::col_type const SrcB3 = m2[3]; - - mat<4, 4, T, Q> Result; - Result[0] = glm::fma(SrcA3, splatW(SrcB0), glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0)))); - Result[1] = glm::fma(SrcA3, splatW(SrcB1), glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1)))); - Result[2] = glm::fma(SrcA3, splatW(SrcB2), glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2)))); - Result[3] = glm::fma(SrcA3, splatW(SrcB3), glm::fma(SrcA2, splatZ(SrcB3), glm::fma(SrcA1, splatY(SrcB3), SrcA0 * splatX(SrcB3)))); - return mat < 4, 4, T, Q > (Result); - } - }; - - template - struct mul4x4 - { - GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) - { - typename mat<4, 4, T, Q>::col_type const& SrcA0 = m1[0]; - typename mat<4, 4, T, Q>::col_type const& SrcA1 = m1[1]; - typename mat<4, 4, T, Q>::col_type const& SrcA2 = m1[2]; - typename mat<4, 4, T, Q>::col_type const& SrcA3 = m1[3]; - - typename mat<4, 4, T, Q>::col_type const& SrcB0 = m2[0]; - typename mat<4, 4, T, Q>::col_type const& SrcB1 = m2[1]; - typename mat<4, 4, T, Q>::col_type const& SrcB2 = m2[2]; - typename mat<4, 4, T, Q>::col_type const& SrcB3 = m2[3]; - - mat<4, 4, T, Q> Result; - // note: the following lines are decomposed to have consistent results between simd and non simd code (prevent rounding error because of operation order) - //Result[0] = SrcA3 * SrcB0.w + SrcA2 * SrcB0.z + SrcA1 * SrcB0.y + SrcA0 * SrcB0.x; - //Result[1] = SrcA3 * SrcB1.w + SrcA2 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x; - //Result[2] = SrcA3 * SrcB2.w + SrcA2 * SrcB2.z + SrcA1 * SrcB2.y + SrcA0 * SrcB2.x; - //Result[3] = SrcA3 * SrcB3.w + SrcA2 * SrcB3.z + SrcA1 * SrcB3.y + SrcA0 * SrcB3.x; - - typename mat<4, 4, T, Q>::col_type tmp; - tmp = SrcA0 * SrcB0.x; - tmp += SrcA1 * SrcB0.y; - tmp += SrcA2 * SrcB0.z; - tmp += SrcA3 * SrcB0.w; - Result[0] = tmp; - tmp = SrcA0 * SrcB1.x; - tmp += SrcA1 * SrcB1.y; - tmp += SrcA2 * SrcB1.z; - tmp += SrcA3 * SrcB1.w; - Result[1] = tmp; - tmp = SrcA0 * SrcB2.x; - tmp += SrcA1 * SrcB2.y; - tmp += SrcA2 * SrcB2.z; - tmp += SrcA3 * SrcB2.w; - Result[2] = tmp; - tmp = SrcA0 * SrcB3.x; - tmp += SrcA1 * SrcB3.y; - tmp += SrcA2 * SrcB3.z; - tmp += SrcA3 * SrcB3.w; - Result[3] = tmp; - - return Result; - } - }; - } - - template GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2) { - return detail::mul4x4::value>::call(m1, m2); + typename mat<4, 4, T, Q>::col_type const SrcA0 = m1[0]; + typename mat<4, 4, T, Q>::col_type const SrcA1 = m1[1]; + typename mat<4, 4, T, Q>::col_type const SrcA2 = m1[2]; + typename mat<4, 4, T, Q>::col_type const SrcA3 = m1[3]; + + typename mat<4, 4, T, Q>::col_type const SrcB0 = m2[0]; + typename mat<4, 4, T, Q>::col_type const SrcB1 = m2[1]; + typename mat<4, 4, T, Q>::col_type const SrcB2 = m2[2]; + typename mat<4, 4, T, Q>::col_type const SrcB3 = m2[3]; + + mat<4, 4, T, Q> Result; + Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3]; + Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3]; + Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3]; + Result[3] = SrcA0 * SrcB3[0] + SrcA1 * SrcB3[1] + SrcA2 * SrcB3[2] + SrcA3 * SrcB3[3]; + return Result; } template diff --git a/glm/detail/type_vec2.hpp b/glm/detail/type_vec2.hpp index 66c6137cee..2ddfb435a5 100644 --- a/glm/detail/type_vec2.hpp +++ b/glm/detail/type_vec2.hpp @@ -21,10 +21,6 @@ namespace glm typedef T value_type; typedef vec<2, T, Q> type; typedef vec<2, bool, Q> bool_type; - enum is_aligned - { - value = false - }; // -- Data -- diff --git a/glm/detail/type_vec3.hpp b/glm/detail/type_vec3.hpp index 90de2f8a41..4bf8395d31 100644 --- a/glm/detail/type_vec3.hpp +++ b/glm/detail/type_vec3.hpp @@ -22,11 +22,6 @@ namespace glm typedef vec<3, T, Q> type; typedef vec<3, bool, Q> bool_type; - enum is_aligned - { - value = detail::is_aligned::value - }; - // -- Data -- # if GLM_SILENT_WARNINGS == GLM_ENABLE @@ -258,8 +253,6 @@ namespace glm GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(vec<3, U, Q> const& v); }; - - // -- Unary operators -- template @@ -436,10 +429,6 @@ namespace glm template GLM_FUNC_DECL GLM_CONSTEXPR vec<3, bool, Q> operator||(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2); - - - - }//namespace glm #ifndef GLM_EXTERNAL_TEMPLATE diff --git a/glm/detail/type_vec3.inl b/glm/detail/type_vec3.inl index eeae97ad88..4e44047bac 100644 --- a/glm/detail/type_vec3.inl +++ b/glm/detail/type_vec3.inl @@ -1,7 +1,6 @@ /// @ref core #include "compute_vector_relational.hpp" -#include "compute_vector_decl.hpp" namespace glm { @@ -226,84 +225,120 @@ namespace glm template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(U scalar) { - return (*this = detail::compute_vec_add<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x += static_cast(scalar); + this->y += static_cast(scalar); + this->z += static_cast(scalar); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_add<3, T, Q, detail::is_aligned::value>::call(*this, vec<1, T, Q>(v.x))); + this->x += static_cast(v.x); + this->y += static_cast(v.x); + this->z += static_cast(v.x); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator+=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_add<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x += static_cast(v.x); + this->y += static_cast(v.y); + this->z += static_cast(v.z); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(U scalar) { - return (*this = detail::compute_vec_sub<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x -= static_cast(scalar); + this->y -= static_cast(scalar); + this->z -= static_cast(scalar); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_sub<3, T, Q, detail::is_aligned::value>::call(*this, vec<1, T, Q>(v.x))); + this->x -= static_cast(v.x); + this->y -= static_cast(v.x); + this->z -= static_cast(v.x); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator-=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_sub<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x -= static_cast(v.x); + this->y -= static_cast(v.y); + this->z -= static_cast(v.z); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(U scalar) { - return (*this = detail::compute_vec_mul<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(static_cast(scalar)))); + this->x *= static_cast(scalar); + this->y *= static_cast(scalar); + this->z *= static_cast(scalar); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_mul<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v.x))); + this->x *= static_cast(v.x); + this->y *= static_cast(v.x); + this->z *= static_cast(v.x); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator*=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_mul<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x *= static_cast(v.x); + this->y *= static_cast(v.y); + this->z *= static_cast(v.z); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(U v) { - return (*this = detail::compute_vec_div<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x /= static_cast(v); + this->y /= static_cast(v); + this->z /= static_cast(v); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_div<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v.x))); + this->x /= static_cast(v.x); + this->y /= static_cast(v.x); + this->z /= static_cast(v.x); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator/=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_div<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x /= static_cast(v.x); + this->y /= static_cast(v.y); + this->z /= static_cast(v.z); + return *this; } // -- Increment and decrement operators -- @@ -348,127 +383,180 @@ namespace glm template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(U scalar) { - return (*this = detail::compute_vec_mod<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x %= scalar; + this->y %= scalar; + this->z %= scalar; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_mod<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x %= v.x; + this->y %= v.x; + this->z %= v.x; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator%=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_mod<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x %= v.x; + this->y %= v.y; + this->z %= v.z; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(U scalar) { - return (*this = detail::compute_vec_and<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x &= scalar; + this->y &= scalar; + this->z &= scalar; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_and<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x &= v.x; + this->y &= v.x; + this->z &= v.x; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator&=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_and<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x &= v.x; + this->y &= v.y; + this->z &= v.z; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(U scalar) { - return (*this = detail::compute_vec_or<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x |= scalar; + this->y |= scalar; + this->z |= scalar; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_or<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x |= v.x; + this->y |= v.x; + this->z |= v.x; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator|=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_or<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x |= v.x; + this->y |= v.y; + this->z |= v.z; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(U scalar) { - return (*this = detail::compute_vec_xor<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x ^= scalar; + this->y ^= scalar; + this->z ^= scalar; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_xor<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v.x))); + this->x ^= v.x; + this->y ^= v.x; + this->z ^= v.x; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator^=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_xor<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x ^= v.x; + this->y ^= v.y; + this->z ^= v.z; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(U scalar) { - return (*this = detail::compute_vec_shift_left<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x <<= scalar; + this->y <<= scalar; + this->z <<= scalar; + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_shift_left<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<1, T, Q>(v))); + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.x); + this->z <<= static_cast(v.x); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator<<=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_shift_left<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x <<= static_cast(v.x); + this->y <<= static_cast(v.y); + this->z <<= static_cast(v.z); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(U scalar) { - return (*this = detail::compute_vec_shift_right<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(scalar))); + this->x >>= static_cast(scalar); + this->y >>= static_cast(scalar); + this->z >>= static_cast(scalar); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_shift_right<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.x); + this->z >>= static_cast(v.x); + return *this; } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> & vec<3, T, Q>::operator>>=(vec<3, U, Q> const& v) { - return (*this = detail::compute_vec_shift_right<3, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); - + this->x >>= static_cast(v.x); + this->y >>= static_cast(v.y); + this->z >>= static_cast(v.z); + return *this; } // -- Unary arithmetic operators -- @@ -482,7 +570,10 @@ namespace glm template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v) { - return vec<3, T, Q>(0) -= v; + return vec<3, T, Q>( + -v.x, + -v.y, + -v.z); } // -- Binary arithmetic operators -- @@ -490,122 +581,181 @@ namespace glm template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) += scalar; + return vec<3, T, Q>( + v.x + scalar, + v.y + scalar, + v.z + scalar); } template - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v1, vec<1, T, Q> const& v2) + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v1) += v2; + return vec<3, T, Q>( + v.x + scalar.x, + v.y + scalar.x, + v.z + scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(v) += scalar; + return vec<3, T, Q>( + scalar + v.x, + scalar + v.y, + scalar + v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) += v; + return vec<3, T, Q>( + scalar.x + v.x, + scalar.x + v.y, + scalar.x + v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator+(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) += v2; + return vec<3, T, Q>( + v1.x + v2.x, + v1.y + v2.y, + v1.z + v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) -= scalar; + return vec<3, T, Q>( + v.x - scalar, + v.y - scalar, + v.z - scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) -= scalar.x; + return vec<3, T, Q>( + v.x - scalar.x, + v.y - scalar.x, + v.z - scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) -= v; + return vec<3, T, Q>( + scalar - v.x, + scalar - v.y, + scalar - v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) -= v; + return vec<3, T, Q>( + scalar.x - v.x, + scalar.x - v.y, + scalar.x - v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator-(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) -= v2; + return vec<3, T, Q>( + v1.x - v2.x, + v1.y - v2.y, + v1.z - v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) *= scalar; + return vec<3, T, Q>( + v.x * scalar, + v.y * scalar, + v.z * scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) *= scalar.x; + return vec<3, T, Q>( + v.x * scalar.x, + v.y * scalar.x, + v.z * scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(v) *= scalar; + return vec<3, T, Q>( + scalar * v.x, + scalar * v.y, + scalar * v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(v) *= scalar.x; + return vec<3, T, Q>( + scalar.x * v.x, + scalar.x * v.y, + scalar.x * v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) *= v2; - + return vec<3, T, Q>( + v1.x * v2.x, + v1.y * v2.y, + v1.z * v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) *= 1/scalar; + return vec<3, T, Q>( + v.x / scalar, + v.y / scalar, + v.z / scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) *= 1/scalar.x; + return vec<3, T, Q>( + v.x / scalar.x, + v.y / scalar.x, + v.z / scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) /= v; + return vec<3, T, Q>( + scalar / v.x, + scalar / v.y, + scalar / v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) /= v; + return vec<3, T, Q>( + scalar.x / v.x, + scalar.x / v.y, + scalar.x / v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator/(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) /= v2; + return vec<3, T, Q>( + v1.x / v2.x, + v1.y / v2.y, + v1.z / v2.z); } // -- Binary bit operators -- @@ -613,181 +763,271 @@ namespace glm template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) %= scalar; + return vec<3, T, Q>( + v.x % scalar, + v.y % scalar, + v.z % scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) %= scalar.x; + return vec<3, T, Q>( + v.x % scalar.x, + v.y % scalar.x, + v.z % scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) %= v; + return vec<3, T, Q>( + scalar % v.x, + scalar % v.y, + scalar % v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar.x) %= v; + return vec<3, T, Q>( + scalar.x % v.x, + scalar.x % v.y, + scalar.x % v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator%(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) %= v2; + return vec<3, T, Q>( + v1.x % v2.x, + v1.y % v2.y, + v1.z % v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) &= scalar; + return vec<3, T, Q>( + v.x & scalar, + v.y & scalar, + v.z & scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) &= scalar.x; + return vec<3, T, Q>( + v.x & scalar.x, + v.y & scalar.x, + v.z & scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) &= v; + return vec<3, T, Q>( + scalar & v.x, + scalar & v.y, + scalar & v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar.x) &= v; + return vec<3, T, Q>( + scalar.x & v.x, + scalar.x & v.y, + scalar.x & v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator&(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) &= v2; + return vec<3, T, Q>( + v1.x & v2.x, + v1.y & v2.y, + v1.z & v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) |= scalar; + return vec<3, T, Q>( + v.x | scalar, + v.y | scalar, + v.z | scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) |= scalar.x; + return vec<3, T, Q>( + v.x | scalar.x, + v.y | scalar.x, + v.z | scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) |= v; + return vec<3, T, Q>( + scalar | v.x, + scalar | v.y, + scalar | v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar.x) |= v; + return vec<3, T, Q>( + scalar.x | v.x, + scalar.x | v.y, + scalar.x | v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator|(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) |= v2; + return vec<3, T, Q>( + v1.x | v2.x, + v1.y | v2.y, + v1.z | v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) ^= scalar; + return vec<3, T, Q>( + v.x ^ scalar, + v.y ^ scalar, + v.z ^ scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) ^= scalar.x; + return vec<3, T, Q>( + v.x ^ scalar.x, + v.y ^ scalar.x, + v.z ^ scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) ^= v; + return vec<3, T, Q>( + scalar ^ v.x, + scalar ^ v.y, + scalar ^ v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar.x) ^= v; + return vec<3, T, Q>( + scalar.x ^ v.x, + scalar.x ^ v.y, + scalar.x ^ v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator^(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) ^= v2; + return vec<3, T, Q>( + v1.x ^ v2.x, + v1.y ^ v2.y, + v1.z ^ v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) <<= scalar; + return vec<3, T, Q>( + v.x << scalar, + v.y << scalar, + v.z << scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) <<= scalar.x; + return vec<3, T, Q>( + v.x << scalar.x, + v.y << scalar.x, + v.z << scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) << v; + return vec<3, T, Q>( + scalar << v.x, + scalar << v.y, + scalar << v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar.x) << v; + return vec<3, T, Q>( + scalar.x << v.x, + scalar.x << v.y, + scalar.x << v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator<<(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) <<= v2; + return vec<3, T, Q>( + v1.x << v2.x, + v1.y << v2.y, + v1.z << v2.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, T scalar) { - return vec<3, T, Q>(v) >>= scalar; + return vec<3, T, Q>( + v.x >> scalar, + v.y >> scalar, + v.z >> scalar); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v, vec<1, T, Q> const& scalar) { - return vec<3, T, Q>(v) >>= scalar.x; + return vec<3, T, Q>( + v.x >> scalar.x, + v.y >> scalar.x, + v.z >> scalar.x); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(T scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar) >>= v; + return vec<3, T, Q>( + scalar >> v.x, + scalar >> v.y, + scalar >> v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<1, T, Q> const& scalar, vec<3, T, Q> const& v) { - return vec<3, T, Q>(scalar.x) >>= v; + return vec<3, T, Q>( + scalar.x >> v.x, + scalar.x >> v.y, + scalar.x >> v.z); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator>>(vec<3, T, Q> const& v1, vec<3, T, Q> const& v2) { - return vec<3, T, Q>(v1) >>= v2; + return vec<3, T, Q>( + v1.x >> v2.x, + v1.y >> v2.y, + v1.z >> v2.z); } template @@ -828,158 +1068,3 @@ namespace glm return vec<3, bool, Q>(v1.x || v2.x, v1.y || v2.y, v1.z || v2.z); } }//namespace glm - - -#if GLM_CONFIG_SIMD == GLM_ENABLE -# include "type_vec_simd.inl" - -namespace glm { - -#if (GLM_ARCH & GLM_ARCH_NEON_BIT) && !GLM_CONFIG_XYZW_ONLY - CTORSL(3, CTOR_FLOAT); - CTORSL(3, CTOR_INT); - CTORSL(3, CTOR_UINT); - CTORSL(3, CTOR_VECF_INT3); - CTORSL(3, CTOR_VECF_UINT3); - CTORSL(3, CTOR_VECF_VECF); - CTORSL(3, CTOR_VECF_VECI); - CTORSL(3, CTOR_VECF_VECU); -#endif - -#if GLM_ARCH & GLM_ARCH_SSE2_BIT - CTORSL(3, CTOR_FLOAT_COPY3); - CTORSL(3, CTOR_DOUBLE_COPY3); - CTORSL(3, CTOR_FLOAT); - CTORSL(3, CTOR_FLOAT3); - CTORSL(3, CTOR_DOUBLE3); - CTORSL(3, CTOR_INT); - CTORSL(3, CTOR_INT3); - CTORSL(3, CTOR_VECF_INT3); - - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, double, aligned_highp>::vec(const vec<3, double, aligned_highp>& v) -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - :data(v.data) {} -#else - { - data.setv(0, v.data.getv(0)); - data.setv(1, v.data.getv(1)); - } -#endif - - - - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, float, aligned_highp>::vec(const vec<3, float, aligned_highp>& v) : - data(v.data) {} - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, float, aligned_highp>::vec(const vec<3, float, packed_highp>& v) - { - data = _mm_set_ps(v[2], v[2], v[1], v[0]); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, float, packed_highp>::vec(const vec<3, float, aligned_highp>& v) - { - _mm_store_sd(reinterpret_cast(this), _mm_castps_pd(v.data)); - __m128 mz = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2)); - _mm_store_ss(reinterpret_cast(this)+2, mz); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, double, aligned_highp>::vec(const vec<3, double, packed_highp>& v) - { -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - data = _mm256_set_pd(v[2], v[2], v[1], v[0]); -#else - data.setv(0, _mm_loadu_pd(reinterpret_cast(&v))); - data.setv(1, _mm_loadu_pd(reinterpret_cast(&v)+2)); -#endif - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, double, packed_highp>::vec(const vec<3, double, aligned_highp>& v) - { -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - __m256d T1 = _mm256_permute_pd(v.data, 1); - _mm_store_sd((reinterpret_cast(this)) + 0, _mm256_castpd256_pd128(v.data)); - _mm_store_sd((reinterpret_cast(this)) + 1, _mm256_castpd256_pd128(T1)); - _mm_store_sd((reinterpret_cast(this)) + 2, _mm256_extractf128_pd(v.data, 1)); -#else - _mm_storeu_pd(reinterpret_cast(this), v.data.getv(0)); - _mm_store_sd((reinterpret_cast(this)) + 2, v.data.getv(1)); -#endif - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, int, aligned_highp>::vec(const vec<3, int, aligned_highp>& v) : - data(v.data) - { - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, int, aligned_highp>::vec(const vec<3, int, packed_highp>& v) - { - __m128 mx = _mm_load_ss(reinterpret_cast(&v[0])); - __m128 my = _mm_load_ss(reinterpret_cast(&v[1])); - __m128 mz = _mm_load_ss(reinterpret_cast(&v[2])); - __m128 mxy = _mm_unpacklo_ps(mx, my); - data = _mm_castps_si128(_mm_movelh_ps(mxy, mz)); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, int, packed_highp>::vec(const vec<3, int, aligned_highp>& v) - { - _mm_store_sd(reinterpret_cast(this), _mm_castsi128_pd(v.data)); - __m128 mz = _mm_shuffle_ps(_mm_castsi128_ps(v.data), _mm_castsi128_ps(v.data), _MM_SHUFFLE(2, 2, 2, 2)); - _mm_store_ss(reinterpret_cast(this)+2, mz); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, unsigned int, aligned_highp>::vec(const vec<3, unsigned int, aligned_highp>& v) : - data(v.data) - { - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, unsigned int, aligned_highp>::vec(const vec<3, unsigned int, packed_highp>& v) - { - __m128 mx = _mm_load_ss(reinterpret_cast(&v[0])); - __m128 my = _mm_load_ss(reinterpret_cast(&v[1])); - __m128 mz = _mm_load_ss(reinterpret_cast(&v[2])); - __m128 mxy = _mm_unpacklo_ps(mx, my); - data = _mm_castps_si128(_mm_movelh_ps(mxy, mz)); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, unsigned int, packed_highp>::vec(const vec<3, unsigned int, aligned_highp>& v) - { - _mm_store_sd(reinterpret_cast(this), _mm_castsi128_pd(v.data)); - __m128 mz = _mm_shuffle_ps(_mm_castsi128_ps(v.data), _mm_castsi128_ps(v.data), _MM_SHUFFLE(2, 2, 2, 2)); - _mm_store_ss(reinterpret_cast(this) + 2, mz); - } - - CTORSL(3, CTOR_DOUBLE); - //CTORSL(3, CTOR_INT64); - -#endif //GLM_ARCH & GLM_ARCH_SSE2_BITt - - -} - -#endif diff --git a/glm/detail/type_vec4.hpp b/glm/detail/type_vec4.hpp index 9ba11229f6..15f122f968 100644 --- a/glm/detail/type_vec4.hpp +++ b/glm/detail/type_vec4.hpp @@ -21,11 +21,6 @@ namespace glm typedef T value_type; typedef vec<4, T, Q> type; typedef vec<4, bool, Q> bool_type; - - enum is_aligned - { - value = detail::is_aligned::value - }; // -- Data -- @@ -240,13 +235,13 @@ namespace glm } template - GLM_FUNC_DISCARD_DECL vec(detail::_swizzle<3, T, Q, E0, E1, E2, 3> const& v, T const& w) + GLM_FUNC_DISCARD_DECL vec(detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v, T const& w) { *this = vec<4, T, Q>(v(), w); } template - GLM_FUNC_DISCARD_DECL vec(T const& x, detail::_swizzle<3, T, Q, E0, E1, E2, 3> const& v) + GLM_FUNC_DISCARD_DECL vec(T const& x, detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v) { *this = vec<4, T, Q>(x, v()); } @@ -330,7 +325,6 @@ namespace glm GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(vec<4, U, Q> const& v); }; - // -- Unary operators -- template diff --git a/glm/detail/type_vec4.inl b/glm/detail/type_vec4.inl index 79a51b6f34..d48fae758e 100644 --- a/glm/detail/type_vec4.inl +++ b/glm/detail/type_vec4.inl @@ -1,12 +1,130 @@ /// @ref core #include "compute_vector_relational.hpp" -#include "compute_vector_decl.hpp" namespace glm{ namespace detail { + template + struct compute_vec4_add + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); + } + }; + + template + struct compute_vec4_sub + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); + } + }; + + template + struct compute_vec4_mul + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); + } + }; + + template + struct compute_vec4_div + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); + } + }; + + template + struct compute_vec4_mod + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x % b.x, a.y % b.y, a.z % b.z, a.w % b.w); + } + }; + + template + struct compute_vec4_and + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x & b.x, a.y & b.y, a.z & b.z, a.w & b.w); + } + }; + + template + struct compute_vec4_or + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x | b.x, a.y | b.y, a.z | b.z, a.w | b.w); + } + }; + + template + struct compute_vec4_xor + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x ^ b.x, a.y ^ b.y, a.z ^ b.z, a.w ^ b.w); + } + }; + + template + struct compute_vec4_shift_left + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x << b.x, a.y << b.y, a.z << b.z, a.w << b.w); + } + }; + + template + struct compute_vec4_shift_right + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + return vec<4, T, Q>(a.x >> b.x, a.y >> b.y, a.z >> b.z, a.w >> b.w); + } + }; + template + struct compute_vec4_equal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return + detail::compute_equal::is_iec559>::call(v1.x, v2.x) && + detail::compute_equal::is_iec559>::call(v1.y, v2.y) && + detail::compute_equal::is_iec559>::call(v1.z, v2.z) && + detail::compute_equal::is_iec559>::call(v1.w, v2.w); + } + }; + + template + struct compute_vec4_nequal + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) + { + return !compute_vec4_equal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + } + }; + + template + struct compute_vec4_bitwise_not + { + GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + return vec<4, T, Q>(~v.x, ~v.y, ~v.z, ~v.w); + } + }; }//namespace detail // -- Implicit basic constructors -- @@ -40,7 +158,7 @@ namespace detail : x(scalar), y(scalar), z(scalar), w(scalar) {} - template + template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(T _x, T _y, T _z, T _w) : x(_x), y(_y), z(_z), w(_w) {} @@ -355,7 +473,6 @@ namespace detail , w(static_cast(v.w)) {} - // -- Component accesses -- template @@ -423,84 +540,84 @@ namespace detail template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(U scalar) { - return (*this = detail::compute_vec_add<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_add<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v.x))); + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(v.x))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_add<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_add::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(U scalar) { - return (*this = detail::compute_vec_sub<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_sub<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v.x))); + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(v.x))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_sub<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_sub::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(U scalar) { - return (*this = detail::compute_vec_mul<4,T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_mul<4,T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v.x))); + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(v.x))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_mul<4,T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_mul::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(U scalar) { - return (*this = detail::compute_vec_div<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_div<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v.x))); + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(v.x))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_div<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_div::value>::call(*this, vec<4, T, Q>(v))); } // -- Increment and decrement operators -- @@ -547,126 +664,126 @@ namespace detail template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(U scalar) { - return (*this = detail::compute_vec_mod<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_mod<3, T, Q, detail::is_aligned::value>::call(*this, vec<3, T, Q>(v))); + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_mod<4, T, Q, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_mod::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(U scalar) { - return (*this = detail::compute_vec_and<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_and<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_and<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_and::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(U scalar) { - return (*this = detail::compute_vec_or<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_or<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_or<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_or::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(U scalar) { - return (*this = detail::compute_vec_xor<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_xor<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_xor<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_xor::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(U scalar) { - return (*this = detail::compute_vec_shift_left<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_shift_left<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_shift_left<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_shift_left::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(U scalar) { - return (*this = detail::compute_vec_shift_right<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(scalar))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<1, U, Q> const& v) { - return (*this = detail::compute_vec_shift_right<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } template template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<4, U, Q> const& v) { - return (*this = detail::compute_vec_shift_right<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); + return (*this = detail::compute_vec4_shift_right::value, sizeof(T) * 8, detail::is_aligned::value>::call(*this, vec<4, T, Q>(v))); } // -- Unary constant operators -- @@ -990,7 +1107,7 @@ namespace detail template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator~(vec<4, T, Q> const& v) { - return detail::compute_vec_bitwise_not<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(v); + return detail::compute_vec4_bitwise_not::value, sizeof(T) * 8, detail::is_aligned::value>::call(v); } // -- Boolean operators -- @@ -998,13 +1115,13 @@ namespace detail template GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) { - return detail::compute_vec_equal<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + return detail::compute_vec4_equal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); } template GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2) { - return detail::compute_vec_nequal<4, T, Q, detail::is_int::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); + return detail::compute_vec4_nequal::value, sizeof(T) * 8, detail::is_aligned::value>::call(v1, v2); } template @@ -1021,110 +1138,5 @@ namespace detail }//namespace glm #if GLM_CONFIG_SIMD == GLM_ENABLE -# include "type_vec_simd.inl" - -namespace glm { -#if GLM_ARCH & GLM_ARCH_NEON_BIT && !GLM_CONFIG_XYZW_ONLY - CTORSL(4, CTOR_FLOAT); - CTORSL(4, CTOR_INT); - CTORSL(4, CTOR_UINT); - CTORSL(4, CTOR_VECF_INT4); - CTORSL(4, CTOR_VECF_UINT4); - CTORSL(4, CTOR_VECF_VECF); - CTORSL(4, CTOR_VECF_VECI); - CTORSL(4, CTOR_VECF_VECU); - - -#endif// GLM_ARCH & GLM_ARCH_NEON_BIT - -#if GLM_ARCH & GLM_ARCH_SSE2_BIT - CTORSL(4, CTOR_FLOAT); - CTORSL(4, CTOR_DOUBLE); - CTORSL(4, CTOR_FLOAT4); - CTORSL(4, CTOR_DOUBLE4); - CTORSL(4, CTOR_INT); - CTORSL(4, CTOR_INT4); - CTORSL(4, CTOR_VECF_INT4); - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, aligned_highp>& v): - data(v.data) - { - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, packed_highp>& v) - { - data = _mm_loadu_ps(reinterpret_cast(&v)); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, packed_highp>::vec(const vec<4, float, aligned_highp>& v) - { - _mm_storeu_ps(reinterpret_cast(this), v.data); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(const vec<4, int, aligned_highp>& v) : - data(v.data) - { - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(const vec<4, int, packed_highp>& v) - { - data = _mm_loadu_si128(reinterpret_cast(&v)); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, packed_highp>::vec(const vec<4, int, aligned_highp>& v) - { - _mm_storeu_si128(reinterpret_cast<__m128i*>(this), v.data); - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(const vec<4, double, aligned_highp>& v) - { -# if (GLM_ARCH & GLM_ARCH_AVX_BIT) - data = v.data; -#else - data.setv(0, v.data.getv(0)); - data.setv(1, v.data.getv(1)); -#endif - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(const vec<4, double, packed_highp>& v) - { -# if (GLM_ARCH & GLM_ARCH_AVX_BIT) - data = _mm256_loadu_pd(reinterpret_cast(&v)); -#else - data.setv(0, _mm_loadu_pd(reinterpret_cast(&v))); - data.setv(1, _mm_loadu_pd(reinterpret_cast(&v)+2)); -#endif - } - - template<> - template<> - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, packed_highp>::vec(const vec<4, double, aligned_highp>& v) - { -# if (GLM_ARCH & GLM_ARCH_AVX_BIT) - _mm256_storeu_pd(reinterpret_cast(this), v.data); -#else - _mm_storeu_pd(reinterpret_cast(this), v.data.getv(0)); - _mm_storeu_pd(reinterpret_cast(this) + 2, v.data.getv(1)); -#endif - } - -#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT -} - +# include "type_vec4_simd.inl" #endif diff --git a/glm/detail/type_vec4_simd.inl b/glm/detail/type_vec4_simd.inl new file mode 100644 index 0000000000..816ef45bf0 --- /dev/null +++ b/glm/detail/type_vec4_simd.inl @@ -0,0 +1,788 @@ +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + +namespace glm { + namespace detail + { +# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + template + struct _swizzle_base1<4, float, Q, E0, E1, E2, E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, float, Q> operator ()() const + { + __m128 data = *reinterpret_cast<__m128 const*>(&this->_buffer); + + vec<4, float, Q> Result; +# if GLM_ARCH & GLM_ARCH_AVX_BIT + Result.data = _mm_permute_ps(data, _MM_SHUFFLE(E3, E2, E1, E0)); +# else + Result.data = _mm_shuffle_ps(data, data, _MM_SHUFFLE(E3, E2, E1, E0)); +# endif + return Result; + } + }; + + template + struct _swizzle_base1<4, int, Q, E0, E1, E2, E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, int, Q> operator ()() const + { + __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); + + vec<4, int, Q> Result; + Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); + return Result; + } + }; + + template + struct _swizzle_base1<4, uint, Q, E0, E1, E2, E3, true> : public _swizzle_base0 + { + GLM_FUNC_QUALIFIER vec<4, uint, Q> operator ()() const + { + __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); + + vec<4, uint, Q> Result; + Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); + return Result; + } + }; +# endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR + + template + struct compute_vec4_add + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_add_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_add + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_add_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_sub + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_sub_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_sub + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_sub_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_mul + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_mul_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_mul + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_mul_pd(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_div + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = _mm_div_ps(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template + struct compute_vec4_div + { + static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b) + { + vec<4, double, Q> Result; + Result.data = _mm256_div_pd(a.data, b.data); + return Result; + } + }; +# endif + + template<> + struct compute_vec4_div + { + static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& a, vec<4, float, aligned_lowp> const& b) + { + vec<4, float, aligned_lowp> Result; + Result.data = _mm_mul_ps(a.data, _mm_rcp_ps(b.data)); + return Result; + } + }; + + template + struct compute_vec4_and + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_and_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_and + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_and_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_or + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_or_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_or + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_or_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_xor + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_xor_si128(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_xor + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_xor_si256(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_shift_left + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_sll_epi32(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_shift_left + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_sll_epi64(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_shift_right + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm_srl_epi32(a.data, b.data); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_shift_right + { + static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b) + { + vec<4, T, Q> Result; + Result.data = _mm256_srl_epi64(a.data, b.data); + return Result; + } + }; +# endif + + template + struct compute_vec4_bitwise_not + { + static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + vec<4, T, Q> Result; + Result.data = _mm_xor_si128(v.data, _mm_set1_epi32(-1)); + return Result; + } + }; + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template + struct compute_vec4_bitwise_not + { + static vec<4, T, Q> call(vec<4, T, Q> const& v) + { + vec<4, T, Q> Result; + Result.data = _mm256_xor_si256(v.data, _mm_set1_epi32(-1)); + return Result; + } + }; +# endif + + template + struct compute_vec4_equal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) == 0; + } + }; + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + template + struct compute_vec4_equal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + //return _mm_movemask_epi8(_mm_cmpeq_epi32(v1.data, v2.data)) != 0; + __m128i neq = _mm_xor_si128(v1.data, v2.data); + return _mm_test_all_zeros(neq, neq) == 0; + } + }; +# endif + + template + struct compute_vec4_nequal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) != 0; + } + }; + +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + template + struct compute_vec4_nequal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + //return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0; + __m128i neq = _mm_xor_si128(v1.data, v2.data); + return _mm_test_all_zeros(neq, neq) != 0; + } + }; +# endif + }//namespace detail + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) : + data(_mm_set1_ps(_s)) + {} + +# if GLM_ARCH & GLM_ARCH_AVX_BIT + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_lowp>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_mediump>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(double _s) : + data(_mm256_set1_pd(_s)) + {} +# endif + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) : + data(_mm_set1_epi32(_s)) + {} + +# if GLM_ARCH & GLM_ARCH_AVX2_BIT + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_lowp>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_mediump>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_highp>::vec(detail::int64 _s) : + data(_mm256_set1_epi64x(_s)) + {} +# endif + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _x, float _y, float _z, float _w) : + data(_mm_set_ps(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_set_epi32(_w, _z, _y, _x)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x))) + {} +}//namespace glm + +#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT + +#if GLM_ARCH & GLM_ARCH_NEON_BIT +namespace glm { + namespace detail { + + template + struct compute_vec4_add + { + static + vec<4, float, Q> + call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vaddq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_add + { + static + vec<4, uint, Q> + call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vaddq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_add + { + static + vec<4, int, Q> + call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, int, Q> Result; + Result.data = vaddq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vsubq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vsubq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_sub + { + static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, int, Q> Result; + Result.data = vsubq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; + Result.data = vmulq_f32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b) + { + vec<4, uint, Q> Result; + Result.data = vmulq_u32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_mul + { + static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b) + { + vec<4, int, Q> Result; + Result.data = vmulq_s32(a.data, b.data); + return Result; + } + }; + + template + struct compute_vec4_div + { + static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b) + { + vec<4, float, Q> Result; +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + Result.data = vdivq_f32(a.data, b.data); +#else + /* Arm assembler reference: + * + * The Newton-Raphson iteration: x[n+1] = x[n] * (2 - d * x[n]) + * converges to (1/d) if x0 is the result of VRECPE applied to d. + * + * Note: The precision usually improves with two interactions, but more than two iterations are not helpful. */ + float32x4_t x = vrecpeq_f32(b.data); + x = vmulq_f32(vrecpsq_f32(b.data, x), x); + x = vmulq_f32(vrecpsq_f32(b.data, x), x); + Result.data = vmulq_f32(a.data, x); +#endif + return Result; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + uint32x4_t cmp = vceqq_f32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + uint32x4_t cmp = vceqq_u32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_equal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + uint32x4_t cmp = vceqq_s32(v1.data, v2.data); +#if GLM_ARCH & GLM_ARCH_ARMV8_BIT + cmp = vpminq_u32(cmp, cmp); + cmp = vpminq_u32(cmp, cmp); + uint32_t r = cmp[0]; +#else + uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp)); + cmpx2 = vpmin_u32(cmpx2, cmpx2); + uint32_t r = cmpx2[0]; +#endif + return r == ~0u; + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + + template + struct compute_vec4_nequal + { + static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2) + { + return !compute_vec4_equal::call(v1, v2); + } + }; + + }//namespace detail + +#if !GLM_CONFIG_XYZW_ONLY + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) : + data(vdupq_n_f32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) : + data(vdupq_n_s32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_lowp>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_mediump>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_highp>::vec(uint _s) : + data(vdupq_n_u32(_s)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, aligned_highp>& rhs) : + data(rhs.data) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, int, aligned_highp>& rhs) : + data(vcvtq_f32_s32(rhs.data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, uint, aligned_highp>& rhs) : + data(vcvtq_f32_u32(rhs.data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_lowp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_mediump>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) : + data(vcvtq_f32_s32(vec<4, int, aligned_highp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_lowp>(_x, _y, _z, _w).data)) + {} + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_mediump>(_x, _y, _z, _w).data)) + {} + + + template<> + template<> + GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(uint _x, uint _y, uint _z, uint _w) : + data(vcvtq_f32_u32(vec<4, uint, aligned_highp>(_x, _y, _z, _w).data)) + {} + +#endif +}//namespace glm + +#endif diff --git a/glm/detail/type_vec_simd.inl b/glm/detail/type_vec_simd.inl deleted file mode 100644 index 566abec3e6..0000000000 --- a/glm/detail/type_vec_simd.inl +++ /dev/null @@ -1,1032 +0,0 @@ -#pragma once - -#define CTORSL(L, CTOR)\ -CTOR(L, aligned_lowp)\ -CTOR(L, aligned_mediump)\ -CTOR(L, aligned_highp)\ - -namespace glm { - namespace detail - { - -template -struct compute_vec_and : public compute_vec_and -{}; - -template -struct compute_vec_or: public compute_vec_or -{}; - -template -struct compute_vec_xor : public compute_vec_xor -{}; - -template -struct compute_vec_shift_left : public compute_vec_shift_left -{}; - -template -struct compute_vec_shift_right : public compute_vec_shift_right -{}; - -template -struct compute_vec_bitwise_not:public compute_vec_bitwise_not -{}; - -template -struct compute_vec_equal : public compute_vec_equal -{}; - -template -struct compute_vec_nequal : public compute_vec_nequal -{}; - -template -struct compute_vec_mod : public compute_vec_mod -{}; - - -template -struct compute_vec_add : public compute_vec_add -{}; - -template< length_t L, typename T, qualifier Q> -struct compute_vec_sub : public compute_vec_sub -{}; - -template< length_t L, typename T, qualifier Q> -struct compute_vec_mul : public compute_vec_mul -{}; - -template< length_t L, typename T, qualifier Q> -struct compute_vec_div : public compute_vec_div -{}; - -#if GLM_ARCH & GLM_ARCH_SSE2_BIT - -# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR - template - struct _swizzle_base1 : public _swizzle_base0 - { - GLM_FUNC_QUALIFIER vec operator ()() const - { - __m128 data = *reinterpret_cast<__m128 const*>(&this->_buffer); - - vec Result; -# if GLM_ARCH & GLM_ARCH_AVX_BIT - Result.data = _mm_permute_ps(data, _MM_SHUFFLE(E3, E2, E1, E0)); -# else - Result.data = _mm_shuffle_ps(data, data, _MM_SHUFFLE(E3, E2, E1, E0)); -# endif - return Result; - } - }; - - template - struct _swizzle_base1<2, float, Q, E0, E1, E2, E3, true> : public _swizzle_base1<2, float, Q, E0, E1, E2, E3, false> {}; - - template - struct _swizzle_base1<2, int, Q, E0, E1, E2, E3, true> : public _swizzle_base1<2, int, Q, E0, E1, E2, E3, false> {}; - - template - struct _swizzle_base1 : public _swizzle_base0 - { - GLM_FUNC_QUALIFIER vec operator ()() const - { - __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); - - vec Result; - Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); - return Result; - } - }; - - template - struct _swizzle_base1 : public _swizzle_base0 - { - GLM_FUNC_QUALIFIER vec operator ()() const - { - __m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer); - - vec Result; - Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0)); - return Result; - } - }; -# endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR - - - template - struct compute_vec_add - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_add_ps(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_add - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_add_epi32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_add - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; -# if (GLM_ARCH & GLM_ARCH_AVX_BIT) - Result.data = _mm256_add_pd(a.data, b.data); -#else - Result.data.setv(0, _mm_add_pd(a.data.getv(0), b.data.getv(0))); - Result.data.setv(1, _mm_add_pd(a.data.getv(1), b.data.getv(1))); -#endif - return Result; - } - }; - - template - struct compute_vec_sub - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_sub_ps(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_sub - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_sub_epi32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_sub - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - Result.data = _mm256_sub_pd(a.data, b.data); -#else - Result.data.setv(0, _mm_sub_pd(a.data.getv(0), b.data.getv(0))); - Result.data.setv(1, _mm_sub_pd(a.data.getv(1), b.data.getv(1))); -#endif - return Result; - } - }; - - template - struct compute_vec_mul - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_mul_ps(a.data, b.data); - return Result; - } - }; - - - template - struct compute_vec_mul - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; -#if (GLM_ARCH & GLM_ARCH_AVX_BIT) - Result.data = _mm256_mul_pd(a.data, b.data); -#else - Result.data.setv(0, _mm_mul_pd(a.data.getv(0), b.data.getv(0))); - Result.data.setv(1, _mm_mul_pd(a.data.getv(1), b.data.getv(1))); -#endif - return Result; - } - }; - - template - struct compute_vec_mul - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - glm_i32vec4 ia = a.data; - glm_i32vec4 ib = b.data; -#ifdef __SSE4_1__ // modern CPU - use SSE 4.1 - Result.data = _mm_mullo_epi32(ia, ib); -#else // old CPU - use SSE 2 - __m128i tmp1 = _mm_mul_epu32(ia, ib); /* mul 2,0*/ - __m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(ia, 4), _mm_srli_si128(ib, 4)); /* mul 3,1 */ - Result.data = _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0))); /* shuffle results to [63..0] and pack */ -#endif - return Result; - } - }; - - template - struct compute_vec_div - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_div_ps(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_div - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { -#if defined(_MSC_VER) && _MSC_VER >= 1920 //_mm_div_epi32 only defined with VS >= 2019 - vec Result; - Result.data = _mm_div_epi32(a.data, b.data); - return Result; -#else - return compute_vec_div::call(a, b); -#endif - } - }; - - - // note: div on uninitialized w can generate div by 0 exception - template - struct compute_vec_div<3, int, Q, true> - { - - GLM_FUNC_QUALIFIER static vec<3, int, Q> call(vec<3, int, Q> const& a, vec<3, int, Q> const& b) - { -#if defined(_MSC_VER) && _MSC_VER >= 1920 //_mm_div_epi32 only defined with VS >= 2019 - vec<3, int, Q> Result; - glm_i32vec4 bv = b.data; - bv = _mm_shuffle_epi32(bv, _MM_SHUFFLE(0, 2, 1, 0)); - Result.data = _mm_div_epi32(a.data, bv); - return Result; -#else - return compute_vec_div<3, int, Q, false>::call(a, b); -#endif - } - }; - - - template - struct compute_vec_div - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; -# if GLM_ARCH & GLM_ARCH_AVX_BIT - Result.data = _mm256_div_pd(a.data, b.data); -# else - Result.data.setv(0, _mm_div_pd(a.data.getv(0), b.data.getv(0))); - Result.data.setv(1, _mm_div_pd(a.data.getv(1), b.data.getv(1))); -# endif - return Result; - } - }; - - template - struct compute_vec_div - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_mul_ps(a.data, _mm_rcp_ps(b.data)); - return Result; - } - }; - - template - struct compute_vec_and - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_and_si128(a.data, b.data); - return Result; - } - }; - - - template - struct compute_vec_and - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; -# if GLM_ARCH & GLM_ARCH_AVX2_BIT - Result.data = _mm256_and_si256(a.data, b.data); -# elif GLM_ARCH & GLM_ARCH_AVX_BIT - Result.data = _mm256_and_pd(_mm256_castpd256_pd128(a.data), _mm256_castpd256_pd128(b.data)); -# else - Result.data.setv(0, _mm_and_si128(a.data.getv(0), b.data.getv(0))); - Result.data.setv(1, _mm_and_si128(a.data.getv(1), b.data.getv(1))); -# endif - return Result; - } - }; - - - - template - struct compute_vec_or - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_or_si128(a.data, b.data); - return Result; - } - }; - - - template - struct compute_vec_or - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; -# if GLM_ARCH & GLM_ARCH_AVX2_BIT - Result.data = _mm256_or_si256(a.data, b.data); -# else - Result.data.setv(0, _mm_or_si128(a.data.getv(0), b.data.getv(0))); - Result.data.setv(1, _mm_or_si128(a.data.getv(1), b.data.getv(1))); -# endif - return Result; - } - }; - - template - struct compute_vec_xor - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = _mm_xor_si128(a.data, b.data); - return Result; - } - }; - - - template - struct compute_vec_xor - { - GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - { - vec Result; -# if GLM_ARCH & GLM_ARCH_AVX2_BIT - Result.data = _mm256_xor_si256(a.data, b.data); -# else - Result.data.setv(0, _mm_xor_si128(a.data.getv(0), b.data.getv(0))); - Result.data.setv(1, _mm_xor_si128(a.data.getv(1), b.data.getv(1))); -# endif - return Result; - } - }; - - - //template - //struct compute_vec_shift_left<3, T, Q, -1, 32, true> - //{ - // GLM_FUNC_QUALIFIER static vec<3, T, Q> call(vec<3, T, Q> const& a, vec<3, T, Q> const& b) - // { - // vec<3, T, Q> Result; - // __m128 v2 = _mm_castsi128_ps(b.data); - // v2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(0, 0, 0, 0)); // note: shift is done with xmm[3] that correspond vec w that doesn't exist on vect3 - // _mm_set1_epi64x(_w, _z, _y, _x); - // __m128i vr = _mm_sll_epi32(a.data, _mm_castps_si128(v2)); - // Result.data = vr; - // return Result; - // } - //}; - - //template - //struct compute_vec_shift_left - //{ - // GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) - // { - // vec Result; - // Result.data = _mm_sll_epi32(a.data, b.data); - // return Result; - // } - //}; - - -// template -// struct compute_vec_shift_left -// { -// GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) -// { -// vec Result; -//# if GLM_ARCH & GLM_ARCH_AVX2_BIT -// Result.data = _mm256_sll_epi64(a.data, b.data); -//# else -// Result.data.setv(0, _mm_sll_epi64(a.data.getv(0), b.data.getv(0))); -// Result.data.setv(1, _mm_sll_epi64(a.data.getv(1), b.data.getv(1))); -//# endif -// return Result; -// } -// }; - - -// template -// struct compute_vec_shift_right -// { -// GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) -// { -// vec Result; -// Result.data = _mm_srl_epi32(a.data, b.data); -// return Result; -// } -// }; -// -// template -// struct compute_vec_shift_right -// { -// GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) -// { -// vec Result; -//# if GLM_ARCH & GLM_ARCH_AVX2_BIT -// Result.data = _mm256_srl_epi64(a.data, b.data); -//# else -// Result.data.setv(0, _mm_srl_epi64(a.data.getv(0), b.data.getv(0))); -// Result.data.setv(1, _mm_srl_epi64(a.data.getv(1), b.data.getv(1))); -//# endif -// return Result; -// } -// }; - - template - struct compute_vec_bitwise_not - { - GLM_FUNC_QUALIFIER static vec call(vec const& v) - { - vec Result; - Result.data = _mm_xor_si128(v.data, _mm_set1_epi32(-1)); - return Result; - } - }; - - - template - struct compute_vec_bitwise_not - { - GLM_FUNC_QUALIFIER static vec call(vec const& v) - { - vec Result; -# if GLM_ARCH & GLM_ARCH_AVX2_BIT - Result.data = _mm256_xor_si256(v.data, _mm256_set1_epi32(-1)); -# else - Result.data.setv(0, _mm_xor_si128(v.data.getv(0), _mm_set1_epi32(-1))); - Result.data.setv(1, _mm_xor_si128(v.data.getv(1), _mm_set1_epi32(-1))); -# endif - return Result; - } - }; - - - template - struct compute_vec_equal - { - GLM_FUNC_QUALIFIER static bool call(vec const& v1, vec const& v2) - { - return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) == 0; - } - }; - -# if GLM_ARCH & GLM_ARCH_SSE41_BIT - template - struct compute_vec_equal - { - GLM_FUNC_QUALIFIER static bool call(vec const& v1, vec const& v2) - { - //return _mm_movemask_epi8(_mm_cmpeq_epi32(v1.data, v2.data)) != 0; - __m128i neq = _mm_xor_si128(v1.data, v2.data); - return _mm_test_all_zeros(neq, neq) == 0; - } - }; -# endif - - - - template - struct compute_vec_nequal - { - GLM_FUNC_QUALIFIER static bool call(vec const& v1, vec const& v2) - { - return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) != 0; - } - }; - -# if GLM_ARCH & GLM_ARCH_SSE41_BIT - template - struct compute_vec_nequal - { - GLM_FUNC_QUALIFIER static bool call(vec const& v1, vec const& v2) - { - //return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0; - __m128i neq = _mm_xor_si128(v1.data, v2.data); - int v = _mm_test_all_zeros(neq, neq); - return v != 1; - } - }; - template - struct compute_vec_nequal - { - GLM_FUNC_QUALIFIER static bool call(vec const& v1, vec const& v2) - { - //return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0; - __m128i neq = _mm_xor_si128(v1.data, v2.data); - return _mm_test_all_zeros(neq, neq) != 1; - } - }; -# else - - - template - struct compute_vec_nequal - { - GLM_FUNC_QUALIFIER static bool call(vec const& v1, vec const& v2) - { - return compute_vec_nequal::call(v1, v2); - } - }; - -# endif - - - - -}//namespace detail - - -#define CTOR_FLOAT(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(float _s) :\ - data(_mm_set1_ps(_s))\ - {} - -#if GLM_ARCH & GLM_ARCH_AVX_BIT -# define CTOR_DOUBLE(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(double _s) :\ - data(_mm256_set1_pd(_s)){} - -#define CTOR_DOUBLE4(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(double _x, double _y, double _z, double _w):\ - data(_mm256_set_pd(_w, _z, _y, _x)) {} - -#define CTOR_DOUBLE3(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(double _x, double _y, double _z):\ - data(_mm256_set_pd(_z, _z, _y, _x)) {} - -# define CTOR_INT64(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(detail::int64 _s) :\ - data(_mm256_set1_epi64x(_s)){} - -#define CTOR_DOUBLE_COPY3(L, Q)\ - template<>\ - template\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, double, Q>::vec(vec<3, double, P> const& v) :\ - data(_mm256_setr_pd(v.x, v.y, v.z, v.z)){} - -#else -# define CTOR_DOUBLE(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(double _v) \ - {\ - data.setv(0, _mm_set1_pd(_v)); \ - data.setv(1, _mm_set1_pd(_v)); \ - } - -#define CTOR_DOUBLE4(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(double _x, double _y, double _z, double _w)\ - {\ - data.setv(0, _mm_setr_pd(_x, _y)); \ - data.setv(1, _mm_setr_pd(_z, _w)); \ - } - -#define CTOR_DOUBLE3(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(double _x, double _y, double _z)\ - {\ - data.setv(0, _mm_setr_pd(_x, _y)); \ - data.setv(1, _mm_setr_pd(_z, _z)); \ - } - -# define CTOR_INT64(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(detail::int64 _s) :\ - data(_mm256_set1_epi64x(_s)){} - -#define CTOR_DOUBLE_COPY3(L, Q)\ - template<>\ - template\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, double, Q>::vec(vec<3, double, P> const& v)\ - {\ - data.setv(0, _mm_setr_pd(v.x, v.y));\ - data.setv(1, _mm_setr_pd(v.z, 1.0));\ - } - -#endif //GLM_ARCH & GLM_ARCH_AVX_BIT - -#define CTOR_INT(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _s) :\ - data(_mm_set1_epi32(_s))\ - {} - -#define CTOR_FLOAT4(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(float _x, float _y, float _z, float _w) :\ - data(_mm_set_ps(_w, _z, _y, _x))\ - {} - -#define CTOR_FLOAT3(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(float _x, float _y, float _z) :\ - data(_mm_set_ps(_z, _z, _y, _x)){} - - -#define CTOR_INT4(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _x, int _y, int _z, int _w) :\ - data(_mm_set_epi32(_w, _z, _y, _x)){} - -#define CTOR_INT3(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _x, int _y, int _z) :\ - data(_mm_set_epi32(_z, _z, _y, _x)){} - -#define CTOR_VECF_INT4(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _x, int _y, int _z, int _w) :\ - data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))\ - {} - -#define CTOR_VECF_INT3(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _x, int _y, int _z) :\ - data(_mm_cvtepi32_ps(_mm_set_epi32(_z, _z, _y, _x)))\ - {} - -#define CTOR_DEFAULT(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec() :\ - data(_mm_setzero_ps())\ - {} - -#define CTOR_FLOAT_COPY3(L, Q)\ - template<>\ - template\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, float, Q>::vec(vec<3, float, P> const& v)\ - :data(_mm_set_ps(v.z, v.z, v.y, v.x))\ - {} - - - -}//namespace glm - -#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT - -#if GLM_ARCH & GLM_ARCH_NEON_BIT - -#if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR -// the functions below needs to be properly implemented, use unoptimized function fro now. - -template -struct _swizzle_base1 : public _swizzle_base1{}; - -template -struct _swizzle_base1 : public _swizzle_base1 {}; - -template -struct _swizzle_base1 : public _swizzle_base1 {}; - -# endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR - - - template - struct compute_vec_add - { - GLM_FUNC_QUALIFIER static - vec - call(vec const& a, vec const& b) - { - vec Result; - Result.data = vaddq_f32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_add - { - GLM_FUNC_QUALIFIER static - vec - call(vec const& a, vec const& b) - { - vec Result; - Result.data = vaddq_u32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_add - { - static - vec - call(vec const& a, vec const& b) - { - vec Result; - Result.data = vaddq_s32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_sub - { - static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = vsubq_f32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_sub - { - static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = vsubq_u32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_sub - { - static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = vsubq_s32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_mul - { - static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = vmulq_f32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_mul - { - static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = vmulq_u32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_mul - { - static vec call(vec const& a, vec const& b) - { - vec Result; - Result.data = vmulq_s32(a.data, b.data); - return Result; - } - }; - - template - struct compute_vec_div - { - static vec call(vec const& a, vec const& b) - { - vec Result; -#if GLM_ARCH & GLM_ARCH_ARMV8_BIT - Result.data = vdivq_f32(a.data, b.data); -#else - /* Arm assembler reference: - * - * The Newton-Raphson iteration: x[n+1] = x[n] * (2 - d * x[n]) - * converges to (1/d) if x0 is the result of VRECPE applied to d. - * - * Note: The precision usually improves with two interactions, but more than two iterations are not helpful. */ - float32x4_t x = vrecpeq_f32(b.data); - x = vmulq_f32(vrecpsq_f32(b.data, x), x); - x = vmulq_f32(vrecpsq_f32(b.data, x), x); - Result.data = vmulq_f32(a.data, x); -#endif - return Result; - } - }; - - template - struct compute_vec_equal - { - static bool call(vec const& v1, vec const& v2) - { - uint32x4_t cmp = vceqq_f32(v1.data, v2.data); -#if GLM_ARCH & GLM_ARCH_ARMV8_BIT - cmp = vpminq_u32(cmp, cmp); - cmp = vpminq_u32(cmp, cmp); - uint32_t r = cmp[0]; -#else - uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp)); - cmpx2 = vpmin_u32(cmpx2, cmpx2); - uint32_t r = cmpx2[0]; -#endif - return r == ~0u; - } - }; - - template - struct compute_vec_equal - { - static bool call(vec const& v1, vec const& v2) - { - uint32x4_t cmp = vceqq_u32(v1.data, v2.data); -#if GLM_ARCH & GLM_ARCH_ARMV8_BIT - cmp = vpminq_u32(cmp, cmp); - cmp = vpminq_u32(cmp, cmp); - uint32_t r = cmp[0]; -#else - uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp)); - cmpx2 = vpmin_u32(cmpx2, cmpx2); - uint32_t r = cmpx2[0]; -#endif - return r == ~0u; - } - }; - - template - struct compute_vec_equal - { - static bool call(vec const& v1, vec const& v2) - { - uint32x4_t cmp = vceqq_s32(v1.data, v2.data); -#if GLM_ARCH & GLM_ARCH_ARMV8_BIT - cmp = vpminq_u32(cmp, cmp); - cmp = vpminq_u32(cmp, cmp); - uint32_t r = cmp[0]; -#else - uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp)); - cmpx2 = vpmin_u32(cmpx2, cmpx2); - uint32_t r = cmpx2[0]; -#endif - return r == ~0u; - } - }; - - template - struct compute_vec_nequal - { - static bool call(vec const& v1, vec const& v2) - { - return !compute_vec_equal::call(v1, v2); - } - }; - - template - struct compute_vec_nequal - { - static bool call(vec const& v1, vec const& v2) - { - return !compute_vec_equal::call(v1, v2); - } - }; - - template - struct compute_vec_nequal - { - static bool call(vec const& v1, vec const& v2) - { - return !compute_vec_equal::call(v1, v2); - } - }; - - -#if !GLM_CONFIG_XYZW_ONLY - -#define CTOR_FLOAT(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(float _s) :\ - data(vdupq_n_f32(_s))\ - {} - -#define CTOR_INT(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _s) :\ - data(vdupq_n_s32(_s))\ - {} - -#define CTOR_UINT(L, Q)\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(uint _s) :\ - data(vdupq_n_u32(_s))\ - {} - -#define CTOR_VECF_INT4(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _x, int _y, int _z, int _w) :\ - data(vcvtq_f32_s32(vec(_x, _y, _z, _w).data))\ - {} - -#define CTOR_VECF_UINT4(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(uint _x, uint _y, uint _z, uint _w) :\ - data(vcvtq_f32_u32(vec(_x, _y, _z, _w).data))\ - {} - -#define CTOR_VECF_INT3(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(int _x, int _y, int _z) :\ - data(vcvtq_f32_s32(vec(_x, _y, _z).data))\ - {} - -#define CTOR_VECF_UINT4(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(uint _x, uint _y, uint _z, uint _w) :\ - data(vcvtq_f32_u32(vec(_x, _y, _z, _w).data))\ - {} - -#define CTOR_VECF_UINT3(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(uint _x, uint _y, uint _z) :\ - data(vcvtq_f32_u32(vec(_x, _y, _z).data))\ - {} - - -#define CTOR_VECF_VECF(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(const vec& rhs) :\ - data(rhs.data)\ - {} - -#define CTOR_VECF_VECI(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(const vec& rhs) :\ - data(vcvtq_f32_s32(rhs.data))\ - {} - -#define CTOR_VECF_VECU(L, Q)\ - template<>\ - template<>\ - GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec::vec(const vec& rhs) :\ - data(vcvtq_f32_u32(rhs.data))\ - {} - - -#endif - - -}//namespace detail - -}//namespace glm - -#endif diff --git a/glm/ext/vector_relational.inl b/glm/ext/vector_relational.inl index 8c50b2ff2a..7a39ab5089 100644 --- a/glm/ext/vector_relational.inl +++ b/glm/ext/vector_relational.inl @@ -10,7 +10,7 @@ namespace glm { return equal(x, y, vec(Epsilon)); } - + template GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec equal(vec const& x, vec const& y, vec const& Epsilon) { diff --git a/glm/gtc/random.inl b/glm/gtc/random.inl index 5724368135..249ec9f92b 100644 --- a/glm/gtc/random.inl +++ b/glm/gtc/random.inl @@ -69,7 +69,7 @@ namespace detail { return (vec(compute_rand::call()) << static_cast(8)) | - (vec(compute_rand::call())); + (vec(compute_rand::call()) << static_cast(0)); } }; @@ -80,7 +80,7 @@ namespace detail { return (vec(compute_rand::call()) << static_cast(16)) | - (vec(compute_rand::call())); + (vec(compute_rand::call()) << static_cast(0)); } }; @@ -91,7 +91,7 @@ namespace detail { return (vec(compute_rand::call()) << static_cast(32)) | - (vec(compute_rand::call())); + (vec(compute_rand::call()) << static_cast(0)); } }; diff --git a/glm/gtx/common.inl b/glm/gtx/common.inl index 4651e35c8a..4575b20752 100644 --- a/glm/gtx/common.inl +++ b/glm/gtx/common.inl @@ -12,7 +12,7 @@ namespace detail { GLM_FUNC_QUALIFIER static vec call(vec const& a, vec const& b) { - return detail::functor2::call(TFmod(), a, b); + return detail::functor2::call(std::fmod, a, b); } }; diff --git a/glm/gtx/vec_swizzle.hpp b/glm/gtx/vec_swizzle.hpp index bce96e8b41..2dafa645f5 100644 --- a/glm/gtx/vec_swizzle.hpp +++ b/glm/gtx/vec_swizzle.hpp @@ -282,6 +282,11 @@ namespace glm { return glm::vec<3, T, Q>(v.x, v.y, v.z); } + template + GLM_FUNC_QUALIFIER glm::vec<3, T, Q> xyz(const glm::vec<4, T, Q> &v) { + return glm::vec<3, T, Q>(v.x, v.y, v.z); + } + // xyw template GLM_FUNC_QUALIFIER glm::vec<3, T, Q> xyw(const glm::vec<4, T, Q> &v) { @@ -1035,6 +1040,16 @@ namespace glm { return glm::vec<4, T, Q>(v.x, v.y, v.z, v.y); } + // xyzz + template + GLM_FUNC_QUALIFIER glm::vec<4, T, Q> xyzz(const glm::vec<3, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z); + } + + template + GLM_FUNC_QUALIFIER glm::vec<4, T, Q> xyzz(const glm::vec<4, T, Q> &v) { + return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z); + } // xyzw template diff --git a/glm/simd/common.h b/glm/simd/common.h index c11338a69a..a580a1f48f 100644 --- a/glm/simd/common.h +++ b/glm/simd/common.h @@ -63,7 +63,7 @@ GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_swizzle_xyzw(glm_f32vec4 a) GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c) { -# ifdef GLM_FORCE_FMA +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG) return _mm_fmadd_ss(a, b, c); # else return _mm_add_ss(_mm_mul_ss(a, b), c); @@ -72,16 +72,7 @@ GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f3 GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c) { -# ifdef GLM_FORCE_FMA - return _mm_fmadd_ps(a, b, c); -# else - return glm_vec4_add(glm_vec4_mul(a, b), c); -# endif -} - -GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4d_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c) -{ -# ifdef GLM_FORCE_FMA +# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG) return _mm_fmadd_ps(a, b, c); # else return glm_vec4_add(glm_vec4_mul(a, b), c); diff --git a/glm/simd/matrix.h b/glm/simd/matrix.h index 8f9461c8b9..b6c42ea4c1 100644 --- a/glm/simd/matrix.h +++ b/glm/simd/matrix.h @@ -166,18 +166,6 @@ GLM_FUNC_QUALIFIER void glm_mat4_transpose(glm_vec4 const in[4], glm_vec4 out[4] out[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD); } -GLM_FUNC_QUALIFIER void glm_mat3_transpose(glm_vec4 const in[3], glm_vec4 out[3]) -{ - __m128 tmp0 = _mm_shuffle_ps(in[0], in[1], 0x44); - __m128 tmp2 = _mm_shuffle_ps(in[0], in[1], 0xEE); - __m128 tmp1 = _mm_shuffle_ps(in[2], in[2], 0x44); - __m128 tmp3 = _mm_shuffle_ps(in[2], in[2], 0xEE); - - out[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88); - out[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD); - out[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88); -} - GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant_highp(glm_vec4 const in[4]) { __m128 Fac0; diff --git a/glm/simd/neon.h b/glm/simd/neon.h index 4bb7c2ed49..f85947f5c1 100644 --- a/glm/simd/neon.h +++ b/glm/simd/neon.h @@ -22,7 +22,7 @@ namespace glm { case 3: return vdupq_n_f32(vgetq_lane_f32(vsrc, 3)); #endif } - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); return vdupq_n_f32(0.0f); } @@ -40,7 +40,7 @@ namespace glm { case 3: return vdup_n_f32(vgetq_lane_f32(vsrc, 3)); #endif } - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); return vdup_n_f32(0.0f); } @@ -54,8 +54,7 @@ namespace glm { case 2: return vcopyq_laneq_f32(vdst, 0, vsrc, 2); case 3: return vcopyq_laneq_f32(vdst, 0, vsrc, 3); } - assert(false); //Unreachable code executed! - break; + assert(!"Unreachable code executed!"); case 1: switch(slane) { case 0: return vcopyq_laneq_f32(vdst, 1, vsrc, 0); @@ -63,8 +62,7 @@ namespace glm { case 2: return vcopyq_laneq_f32(vdst, 1, vsrc, 2); case 3: return vcopyq_laneq_f32(vdst, 1, vsrc, 3); } - assert(false); //Unreachable code executed! - break; + assert(!"Unreachable code executed!"); case 2: switch(slane) { case 0: return vcopyq_laneq_f32(vdst, 2, vsrc, 0); @@ -72,8 +70,7 @@ namespace glm { case 2: return vcopyq_laneq_f32(vdst, 2, vsrc, 2); case 3: return vcopyq_laneq_f32(vdst, 2, vsrc, 3); } - assert(false); //Unreachable code executed! - break; + assert(!"Unreachable code executed!"); case 3: switch(slane) { case 0: return vcopyq_laneq_f32(vdst, 3, vsrc, 0); @@ -81,8 +78,7 @@ namespace glm { case 2: return vcopyq_laneq_f32(vdst, 3, vsrc, 2); case 3: return vcopyq_laneq_f32(vdst, 3, vsrc, 3); } - assert(false); //Unreachable code executed! - break; + assert(!"Unreachable code executed!"); } #else @@ -93,7 +89,7 @@ namespace glm { case 2: l = vgetq_lane_f32(vsrc, 2); break; case 3: l = vgetq_lane_f32(vsrc, 3); break; default: - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); } switch(dlane) { case 0: return vsetq_lane_f32(l, vdst, 0); @@ -102,7 +98,7 @@ namespace glm { case 3: return vsetq_lane_f32(l, vdst, 3); } #endif - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); return vdupq_n_f32(0.0f); } @@ -114,9 +110,9 @@ namespace glm { case 2: return vmulq_laneq_f32(v, vlane, 2); break; case 3: return vmulq_laneq_f32(v, vlane, 3); break; default: - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); } - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); return vdupq_n_f32(0.0f); #else return vmulq_f32(v, dupq_lane(vlane, lane)); @@ -145,9 +141,9 @@ namespace glm { FMADD_LANE(acc, v, vlane, 3); return acc; default: - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); } - assert(false); //Unreachable code executed! + assert(!"Unreachable code executed!"); return vdupq_n_f32(0.0f); # undef FMADD_LANE #else diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7b618ede37..4ed1403f18 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,7 +10,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") message("GLM: Clang - ${CMAKE_CXX_COMPILER_ID} compiler") endif() - add_definitions(-D_CRT_SECURE_NO_WARNINGS) if(NOT GLM_DISABLE_AUTO_DETECTION) add_compile_options(-Werror -Weverything) endif() diff --git a/test/bug/bug_ms_vec_static.cpp b/test/bug/bug_ms_vec_static.cpp index 1645aacbec..f4919d6627 100644 --- a/test/bug/bug_ms_vec_static.cpp +++ b/test/bug/bug_ms_vec_static.cpp @@ -3,7 +3,7 @@ #if GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE struct vec2; -struct swizzleStruct +struct _swizzle { char _buffer[1]; }; @@ -27,7 +27,7 @@ struct vec2 union { struct { float x, y; }; - struct { swizzleStruct xx; }; + struct { _swizzle xx; }; }; #if GLM_COMPILER & GLM_COMPILER_CLANG diff --git a/test/core/core_force_pure.cpp b/test/core/core_force_pure.cpp index bca17b5310..03ec75582a 100644 --- a/test/core/core_force_pure.cpp +++ b/test/core/core_force_pure.cpp @@ -1,7 +1,7 @@ #ifndef GLM_FORCE_PURE # define GLM_FORCE_PURE #endif//GLM_FORCE_PURE -//#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES +#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES #define GLM_FORCE_SWIZZLE #include #include diff --git a/test/core/core_type_aligned.cpp b/test/core/core_type_aligned.cpp index c29593c5d9..63421f8412 100644 --- a/test/core/core_type_aligned.cpp +++ b/test/core/core_type_aligned.cpp @@ -1,7 +1,4 @@ -#ifndef GLM_FORCE_PURE #define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES -#endif - #include #if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE diff --git a/test/gtc/gtc_random.cpp b/test/gtc/gtc_random.cpp index 734c69d342..0c8346179e 100644 --- a/test/gtc/gtc_random.cpp +++ b/test/gtc/gtc_random.cpp @@ -1,6 +1,4 @@ -#ifndef GLM_FORCE_PURE #define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES -#endif #include #include #include diff --git a/test/gtc/gtc_type_aligned.cpp b/test/gtc/gtc_type_aligned.cpp index 610fe3b4fe..7ee3452d9c 100644 --- a/test/gtc/gtc_type_aligned.cpp +++ b/test/gtc/gtc_type_aligned.cpp @@ -200,185 +200,6 @@ static int test_copy_vec3() return Error; } -static int test_splat_vec3() -{ - int Error = 0; - { - glm::aligned_vec3 const u(1.f, 2.f, 3.f); - glm::aligned_vec3 const v(glm::splatX(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.x, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_vec3 const u(1.f, 2.f, 3.f); - glm::aligned_vec3 const v(glm::splatY(u)); - Error += glm::equal(v.x, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.y, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_vec3 const u(1.f, 2.f, 3.f); - glm::aligned_vec3 const v(glm::splatZ(u)); - Error += glm::equal(v.x, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec3 const u(1., 2., 3.); - glm::aligned_dvec3 const v(glm::splatX(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.x, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec3 const u(1., 2., 3.); - glm::aligned_dvec3 const v(glm::splatY(u)); - Error += glm::equal(v.x, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.y, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec3 const u(1., 2., 3.); - glm::aligned_dvec3 const v(glm::splatZ(u)); - Error += glm::equal(v.x, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - } - - return Error; -} - -static int test_splat_vec4() -{ - int Error = 0; - { - glm::aligned_vec4 const u(1.f, 2.f, 3.f, 4.f); - { - glm::aligned_vec4 const v(glm::splatX(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, u.x, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_vec4 const v(glm::splatY(u)); - Error += glm::equal(v.x, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, u.y, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_vec4 const v(glm::splatZ(u)); - Error += glm::equal(v.x, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, u.z, glm::epsilon()) ? 0 : 1; - } - } - { - glm::aligned_dvec4 const u(1.f, 2.f, 3.f, 4.f); - { - glm::aligned_dvec4 const v(glm::splatX(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, u.x, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec4 const v(glm::splatY(u)); - Error += glm::equal(v.x, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, u.y, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec4 const v(glm::splatZ(u)); - Error += glm::equal(v.x, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, u.z, glm::epsilon()) ? 0 : 1; - } - } - return Error; -} - -static int test_copy_vec4_vec3() -{ - int Error = 0; - - { - glm::aligned_vec3 const u(1.f, 2.f, 3.f); - glm::aligned_vec4 const v(glm::xyz0(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, 0.0f, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_vec3 const u(1.f, 2.f, 3.f); - glm::aligned_vec4 const v(glm::xyz1(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, 1.0f, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec3 const u(1., 2., 3.); - glm::aligned_dvec4 const v(glm::xyz0(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, 0.0, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec3 const u(1., 2., 3.); - glm::aligned_dvec4 const v(glm::xyz1(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, 1.0, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec3 const u(1., 2., 3.); - glm::aligned_dvec4 const v(glm::xyzz(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.w, u.z, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_vec4 const u(1.f, 2.f, 3.f, 4.f); - glm::aligned_vec3 const v(glm::xyz(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - } - - { - glm::aligned_dvec4 const u(1., 2., 3., 4.); - glm::aligned_dvec3 const v(glm::xyz(u)); - Error += glm::equal(v.x, u.x, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.y, u.y, glm::epsilon()) ? 0 : 1; - Error += glm::equal(v.z, u.z, glm::epsilon()) ? 0 : 1; - } - return Error; -} - static int test_copy() { int Error = 0; @@ -476,22 +297,15 @@ static int test_aligned_mat4() return Error; } - int main() { int Error = 0; Error += test_ctor(); - Error += test_copy_vec4(); - Error += test_copy_vec3(); - Error += test_splat_vec3(); - Error += test_splat_vec4(); - Error += test_copy_vec4_vec3(); Error += test_copy(); Error += test_aligned_ivec4(); Error += test_aligned_mat4(); - return Error; } diff --git a/test/perf/perf_matrix_mul.cpp b/test/perf/perf_matrix_mul.cpp index db65ff06e6..41e1a92074 100644 --- a/test/perf/perf_matrix_mul.cpp +++ b/test/perf/perf_matrix_mul.cpp @@ -14,31 +14,6 @@ #include #include - -inline bool -is_aligned(const void* ptr, std::uintptr_t alignment) noexcept { - auto iptr = reinterpret_cast(ptr); - return !(iptr % alignment); -} - -template -static void align_check(matType const& M, std::vector const& I, std::vector& O) -{ - if (matType::col_type::is_aligned::value) - { - if (!is_aligned(&M, 16)) - abort(); - for (std::size_t i = 0, n = I.size(); i < n; ++i) - { - if (!is_aligned(&I[i], 16)) - abort(); - - if (!is_aligned(&O[i], 16)) - abort(); - } - } -} - template static void test_mat_mul_mat(matType const& M, std::vector const& I, std::vector& O) { @@ -57,8 +32,6 @@ static int launch_mat_mul_mat(std::vector& O, matType const& Transform, for(std::size_t i = 0; i < Samples; ++i) I[i] = Scale * static_cast(i); - align_check(Transform, I, O); - std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); test_mat_mul_mat(Transform, I, O); std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); @@ -92,49 +65,27 @@ static int comp_mat2_mul_mat2(std::size_t Samples) return Error; } -template -bool percent_error(const T1& a, const T2& b, float percentThreshold) -{ - typedef typename T1::value_type value_type; - for (int i = 0; i < a.length(); ++i) - for (int j = 0; j < a[i].length(); ++j) - { - value_type v; - if (a[i][j] != value_type(0)) - v = ((b[i][j] - a[i][j]) / a[i][j]) * value_type(100); - else - v = b[i][j] * value_type(100); - - if (v > value_type(percentThreshold)) - return false; - } - return true; -} - template static int comp_mat3_mul_mat3(std::size_t Samples) { - + typedef typename packedMatType::value_type T; + int Error = 0; + packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9); + packedMatType const Scale(0.01, 0.02, 0.03, 0.05, 0.01, 0.02, 0.03, 0.05, 0.01); + std::vector SISD; - { - packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9); - packedMatType const Scale(0.01, 0.02, 0.03, 0.05, 0.01, 0.02, 0.03, 0.05, 0.01); - std::printf("- SISD: %d us\n", launch_mat_mul_mat(SISD, Transform, Scale, Samples)); - } + std::printf("- SISD: %d us\n", launch_mat_mul_mat(SISD, Transform, Scale, Samples)); std::vector SIMD; - { - alignedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9); - alignedMatType const Scale(0.01, 0.02, 0.03, 0.05, 0.01, 0.02, 0.03, 0.05, 0.01); - std::printf("- SIMD: %d us\n", launch_mat_mul_mat(SIMD, Transform, Scale, Samples)); - } + std::printf("- SIMD: %d us\n", launch_mat_mul_mat(SIMD, Transform, Scale, Samples)); + for(std::size_t i = 0; i < Samples; ++i) { packedMatType const A = SISD[i]; packedMatType const B = SIMD[i]; - Error += percent_error(A, B, 0.01f) ? 0 : 1; + Error += glm::all(glm::equal(A, B, static_cast(0.001))) ? 0 : 1; } return Error; @@ -143,6 +94,7 @@ static int comp_mat3_mul_mat3(std::size_t Samples) template static int comp_mat4_mul_mat4(std::size_t Samples) { + typedef typename packedMatType::value_type T; int Error = 0; @@ -159,7 +111,7 @@ static int comp_mat4_mul_mat4(std::size_t Samples) { packedMatType const A = SISD[i]; packedMatType const B = SIMD[i]; - Error += percent_error(A, B, 0.01f) ? 0 : 1; + Error += glm::all(glm::equal(A, B, static_cast(0.001))) ? 0 : 1; } return Error; @@ -173,13 +125,13 @@ int main() std::printf("mat2 * mat2:\n"); Error += comp_mat2_mul_mat2(Samples); - + std::printf("dmat2 * dmat2:\n"); Error += comp_mat2_mul_mat2(Samples); std::printf("mat3 * mat3:\n"); Error += comp_mat3_mul_mat3(Samples); - + std::printf("dmat3 * dmat3:\n"); Error += comp_mat3_mul_mat3(Samples); diff --git a/test/perf/perf_matrix_mul_vector.cpp b/test/perf/perf_matrix_mul_vector.cpp index 1111777688..89a77703c0 100644 --- a/test/perf/perf_matrix_mul_vector.cpp +++ b/test/perf/perf_matrix_mul_vector.cpp @@ -72,19 +72,14 @@ static int comp_mat3_mul_vec3(std::size_t Samples) int Error = 0; + packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9); + packedVecType const Scale(0.01, 0.02, 0.05); + std::vector SISD; - { - packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9); - packedVecType const Scale(0.01, 0.02, 0.05); - std::printf("- SISD: %d us\n", launch_mat_mul_vec(SISD, Transform, Scale, Samples)); - } + std::printf("- SISD: %d us\n", launch_mat_mul_vec(SISD, Transform, Scale, Samples)); std::vector SIMD; - { - alignedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9); - alignedVecType const Scale(0.01, 0.02, 0.05); - std::printf("- SIMD: %d us\n", launch_mat_mul_vec(SIMD, Transform, Scale, Samples)); - } + std::printf("- SIMD: %d us\n", launch_mat_mul_vec(SIMD, Transform, Scale, Samples)); for(std::size_t i = 0; i < Samples; ++i) { @@ -130,9 +125,9 @@ int main() std::printf("mat2 * vec2:\n"); Error += comp_mat2_mul_vec2(Samples); - + std::printf("dmat2 * dvec2:\n"); - Error += comp_mat2_mul_vec2(Samples); + Error += comp_mat2_mul_vec2(Samples); std::printf("mat3 * vec3:\n"); Error += comp_mat3_mul_vec3(Samples); diff --git a/test/perf/perf_vector_mul_matrix.cpp b/test/perf/perf_vector_mul_matrix.cpp index 55384e6334..9f59f81ca5 100644 --- a/test/perf/perf_vector_mul_matrix.cpp +++ b/test/perf/perf_vector_mul_matrix.cpp @@ -14,30 +14,14 @@ #include #include -template -struct test_vec_mul_mat {}; - template -struct test_vec_mul_mat< matType, vecType, false> +static void test_vec_mul_mat(matType const& M, std::vector const& I, std::vector& O) { - void operator()(matType const& M, std::vector const& I, std::vector& O) - { - for (std::size_t i = 0, n = I.size(); i < n; ++i) - O[i] = I[i] * M; - } -}; + for (std::size_t i = 0, n = I.size(); i < n; ++i) + O[i] = I[i] * M; +} template -struct test_vec_mul_mat< matType, vecType, true> -{ - void operator()(matType const& M, std::vector const& I, std::vector& O) - { - for (std::size_t i = 0, n = I.size(); i < n; ++i) - O[i] = M * I[i]; - } -}; - -template static int launch_vec_mul_mat(std::vector& O, matType const& Transform, vecType const& Scale, std::size_t Samples) { typedef typename matType::value_type T; @@ -45,20 +29,17 @@ static int launch_vec_mul_mat(std::vector& O, matType const& Transform, std::vector I(Samples); O.resize(Samples); - memset(I.data(), 0, I.size() * sizeof(vecType)); - for(std::size_t i = 0; i < Samples; ++i) I[i] = Scale * static_cast(i); std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); - test_vec_mul_mat fct; - fct(Transform, I, O); + test_vec_mul_mat(Transform, I, O); std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); return static_cast(std::chrono::duration_cast(t2 - t1).count()); } -template +template static int comp_vec2_mul_mat2(std::size_t Samples) { typedef typename packedMatType::value_type T; @@ -69,10 +50,10 @@ static int comp_vec2_mul_mat2(std::size_t Samples) packedVecType const Scale(0.01, 0.02); std::vector SISD; - std::printf("- SISD: %d us\n", launch_vec_mul_mat(SISD, Transform, Scale, Samples)); + std::printf("- SISD: %d us\n", launch_vec_mul_mat(SISD, Transform, Scale, Samples)); std::vector SIMD; - std::printf("- SIMD: %d us\n", launch_vec_mul_mat(SIMD, Transform, Scale, Samples)); + std::printf("- SIMD: %d us\n", launch_vec_mul_mat(SIMD, Transform, Scale, Samples)); for(std::size_t i = 0; i < Samples; ++i) { @@ -84,7 +65,7 @@ static int comp_vec2_mul_mat2(std::size_t Samples) return Error; } -template +template static int comp_vec3_mul_mat3(std::size_t Samples) { typedef typename packedMatType::value_type T; @@ -95,10 +76,10 @@ static int comp_vec3_mul_mat3(std::size_t Samples) packedVecType const Scale(0.01, 0.02, 0.05); std::vector SISD; - std::printf("- SISD: %d us\n", launch_vec_mul_mat(SISD, Transform, Scale, Samples)); + std::printf("- SISD: %d us\n", launch_vec_mul_mat(SISD, Transform, Scale, Samples)); std::vector SIMD; - std::printf("- SIMD: %d us\n", launch_vec_mul_mat(SIMD, Transform, Scale, Samples)); + std::printf("- SIMD: %d us\n", launch_vec_mul_mat(SIMD, Transform, Scale, Samples)); for(std::size_t i = 0; i < Samples; ++i) { @@ -110,7 +91,7 @@ static int comp_vec3_mul_mat3(std::size_t Samples) return Error; } -template +template static int comp_vec4_mul_mat4(std::size_t Samples) { typedef typename packedMatType::value_type T; @@ -121,10 +102,10 @@ static int comp_vec4_mul_mat4(std::size_t Samples) packedVecType const Scale(0.01, 0.02, 0.03, 0.05); std::vector SISD; - std::printf("- SISD: %d us\n", launch_vec_mul_mat(SISD, Transform, Scale, Samples)); + std::printf("- SISD: %d us\n", launch_vec_mul_mat(SISD, Transform, Scale, Samples)); std::vector SIMD; - std::printf("- SIMD: %d us\n", launch_vec_mul_mat(SIMD, Transform, Scale, Samples)); + std::printf("- SIMD: %d us\n", launch_vec_mul_mat(SIMD, Transform, Scale, Samples)); for(std::size_t i = 0; i < Samples; ++i) { @@ -143,41 +124,22 @@ int main() int Error = 0; std::printf("vec2 * mat2:\n"); - Error += comp_vec2_mul_mat2(Samples); - + Error += comp_vec2_mul_mat2(Samples); + std::printf("dvec2 * dmat2:\n"); - Error += comp_vec2_mul_mat2(Samples); + Error += comp_vec2_mul_mat2(Samples); std::printf("vec3 * mat3:\n"); - Error += comp_vec3_mul_mat3(Samples); - + Error += comp_vec3_mul_mat3(Samples); + std::printf("dvec3 * dmat3:\n"); - Error += comp_vec3_mul_mat3(Samples); + Error += comp_vec3_mul_mat3(Samples); std::printf("vec4 * mat4:\n"); - Error += comp_vec4_mul_mat4(Samples); + Error += comp_vec4_mul_mat4(Samples); std::printf("dvec4 * dmat4:\n"); - Error += comp_vec4_mul_mat4(Samples); - - - std::printf("mat2 * vec2:\n"); - Error += comp_vec2_mul_mat2(Samples); - - std::printf("dmat2 * dvec2 :\n"); - Error += comp_vec2_mul_mat2(Samples); - - std::printf("mat3 * vec3:\n"); - Error += comp_vec3_mul_mat3(Samples); - - std::printf("dmat3 * dvec3 :\n"); - Error += comp_vec3_mul_mat3(Samples); - - std::printf("mat4 * vec4 :\n"); - Error += comp_vec4_mul_mat4(Samples); - - std::printf("dmat4 * dvec4 :\n"); - Error += comp_vec4_mul_mat4(Samples); + Error += comp_vec4_mul_mat4(Samples); return Error; }