Browse Source

Removed simd precision qualifier. All precision qualifiers may generate SIMD instructions, precision may affect the generated instructions accordingly

Christophe Riccio 9 years ago
parent
commit
757fe39587

+ 1 - 1
glm/detail/func_geometric.inl

@@ -171,6 +171,6 @@ namespace detail
 	}
 }//namespace glm
 
-#if GLM_ARCH != GLM_ARCH_PURE
+#if GLM_ARCH != GLM_ARCH_PURE && GLM_HAS_UNRESTRICTED_UNIONS
 #	include "func_geometric_simd.inl"
 #endif

+ 10 - 12
glm/detail/func_geometric_simd.inl

@@ -3,20 +3,18 @@
 namespace glm{
 namespace detail
 {
-#	if GLM_HAS_UNRESTRICTED_UNIONS
-		template <>
-		struct compute_dot<tvec4, float, simd>
+	template <precision P>
+	struct compute_dot<tvec4, float, P>
+	{
+		GLM_FUNC_QUALIFIER static float call(tvec4<float, P> const& x, tvec4<float, P> const& y)
 		{
-			GLM_FUNC_QUALIFIER static float call(tvec4<float, simd> const& x, tvec4<float, simd> const& y)
-			{
-				__m128 const dot0 = glm_dot_ss(x.data, y.data);
+			__m128 const dot0 = glm_dot_ss(x.data, y.data);
 
-				float Result = 0;
-				_mm_store_ss(&Result, dot0);
-				return Result;
-			}
-		};
-#	endif//GLM_HAS_UNRESTRICTED_UNIONS
+			float Result = 0;
+			_mm_store_ss(&Result, dot0);
+			return Result;
+		}
+	};
 }//namespace detail
 }//namespace glm
 

+ 111 - 3
glm/detail/func_matrix.inl

@@ -186,7 +186,7 @@ namespace detail
 		}
 	};
 
-	template <template <class, precision> class matType, typename T, precision P>
+	template <template <typename, precision> class matType, typename T, precision P>
 	struct compute_determinant{};
 
 	template <typename T, precision P>
@@ -233,6 +233,114 @@ namespace detail
 				m[0][2] * DetCof[2] + m[0][3] * DetCof[3];
 		}
 	};
+
+	template <template <typename, precision> class matType, typename T, precision P>
+	struct compute_inverse{};
+
+	template <typename T, precision P>
+	struct compute_inverse<tmat2x2, T, P>
+	{
+		GLM_FUNC_QUALIFIER static tmat2x2<T, P> call(tmat2x2<T, P> const& m)
+		{
+			T OneOverDeterminant = static_cast<T>(1) / (
+				+ m[0][0] * m[1][1]
+				- m[1][0] * m[0][1]);
+
+			tmat2x2<T, P> Inverse(
+				+ m[1][1] * OneOverDeterminant,
+				- m[0][1] * OneOverDeterminant,
+				- m[1][0] * OneOverDeterminant,
+				+ m[0][0] * OneOverDeterminant);
+
+			return Inverse;
+		}
+	};
+
+	template <typename T, precision P>
+	struct compute_inverse<tmat3x3, T, P>
+	{
+		GLM_FUNC_QUALIFIER static tmat3x3<T, P> call(tmat3x3<T, P> const& m)
+		{
+			T OneOverDeterminant = static_cast<T>(1) / (
+				+ 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]));
+
+			tmat3x3<T, P> Inverse(uninitialize);
+			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;
+
+			return Inverse;
+		}
+	};
+
+	template <typename T, precision P>
+	struct compute_inverse<tmat4x4, T, P>
+	{
+		GLM_FUNC_QUALIFIER static tmat4x4<T, P> call(tmat4x4<T, P> const& m)
+		{
+			T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+			T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+			T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+
+			T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+			T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+			T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+
+			T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+			T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+			T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+
+			T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+			T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+			T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+
+			T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+			T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+			T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+
+			T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+			T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+			T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+			tvec4<T, P> Fac0(Coef00, Coef00, Coef02, Coef03);
+			tvec4<T, P> Fac1(Coef04, Coef04, Coef06, Coef07);
+			tvec4<T, P> Fac2(Coef08, Coef08, Coef10, Coef11);
+			tvec4<T, P> Fac3(Coef12, Coef12, Coef14, Coef15);
+			tvec4<T, P> Fac4(Coef16, Coef16, Coef18, Coef19);
+			tvec4<T, P> Fac5(Coef20, Coef20, Coef22, Coef23);
+
+			tvec4<T, P> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]);
+			tvec4<T, P> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]);
+			tvec4<T, P> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]);
+			tvec4<T, P> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]);
+
+			tvec4<T, P> Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
+			tvec4<T, P> Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
+			tvec4<T, P> Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
+			tvec4<T, P> Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
+
+			tvec4<T, P> SignA(+1, -1, +1, -1);
+			tvec4<T, P> SignB(-1, +1, -1, +1);
+			tmat4x4<T, P> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB);
+
+			tvec4<T, P> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
+
+			tvec4<T, P> Dot0(m[0] * Row0);
+			T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w);
+
+			T OneOverDeterminant = static_cast<T>(1) / Dot1;
+
+			return Inverse * OneOverDeterminant;
+		}
+	};
 }//namespace detail
 
 	template <typename T, precision P, template <typename, precision> class matType>
@@ -275,11 +383,11 @@ namespace detail
 	GLM_FUNC_QUALIFIER matType<T, P> inverse(matType<T, P> const & m)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'inverse' only accept floating-point inputs");
-		return detail::compute_inverse(m);
+		return detail::compute_inverse<matType, T, P>::call(m);
 	}
 }//namespace glm
 
-#if GLM_ARCH != GLM_ARCH_PURE
+#if GLM_ARCH != GLM_ARCH_PURE && GLM_HAS_UNRESTRICTED_UNIONS
 #	include "func_matrix_simd.inl"
 #endif
 

+ 14 - 11
glm/detail/func_matrix_simd.inl

@@ -5,17 +5,20 @@
 #include "func_geometric.hpp"
 #include "../simd/matrix.h"
 
-namespace glm
+namespace glm{
+namespace detail
 {
-#	if GLM_HAS_UNRESTRICTED_UNIONS
-		template <>
-		GLM_FUNC_QUALIFIER tmat4x4<float, simd> inverse(tmat4x4<float, simd> const& m)
+#	if GLM_ARCH & GLM_ARCH_SSE2
+		template <precision P>
+		struct compute_inverse<tmat4x4, float, P>
 		{
-			tmat4x4<float, simd> Result(uninitialize);
-			glm_inverse_ps(
-				*reinterpret_cast<__m128 const(*)[4]>(&m[0].data),
-				*reinterpret_cast<__m128(*)[4]>(&Result[0].data));
-			return Result;
-		}
-#	endif// GLM_HAS_UNRESTRICTED_UNIONS
+			GLM_FUNC_QUALIFIER static tmat4x4<float, P> call(tmat4x4<float, P> const& m)
+			{
+				tmat4x4<float, P> Result(uninitialize);
+				glm_inverse_ps(*reinterpret_cast<__m128 const(*)[4]>(&m[0].data), *reinterpret_cast<__m128(*)[4]>(&Result[0].data));
+				return Result;
+			}
+		};
+#	endif
+}//namespace detail
 }//namespace glm

+ 0 - 1
glm/detail/precision.hpp

@@ -39,7 +39,6 @@ namespace glm
 		highp,
 		mediump,
 		lowp,
-		simd,
 		defaultp = highp
 	};
 }//namespace glm

+ 0 - 4
glm/detail/setup.hpp

@@ -423,9 +423,6 @@
 #endif
 
 // N2544 Unrestricted unions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf
-
-#define GLM_NOT_BUGGY_VC32BITS (!(GLM_MODEL == GLM_MODEL_32 && (GLM_COMPILER & GLM_COMPILER_VC) && GLM_COMPILER < GLM_COMPILER_VC2013))
-
 #if GLM_COMPILER & GLM_COMPILER_LLVM
 #	define GLM_HAS_UNRESTRICTED_UNIONS __has_feature(cxx_unrestricted_unions)
 #elif GLM_LANG & (GLM_LANG_CXX11_FLAG | GLM_LANG_CXXMS_FLAG)
@@ -433,7 +430,6 @@
 #else
 #	define GLM_HAS_UNRESTRICTED_UNIONS (GLM_LANG & GLM_LANG_CXX0X_FLAG) && (\
 		((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_LANG & GLM_LANG_CXXMS_FLAG)) || \
-		((GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2015)) || \
 		((GLM_COMPILER & GLM_COMPILER_CUDA) && (GLM_COMPILER >= GLM_COMPILER_CUDA75)) || \
 		((GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC46)))
 #endif

+ 3 - 0
glm/detail/type_mat.hpp

@@ -54,6 +54,9 @@ namespace detail
 	template <typename T, precision P> struct tmat4x3;
 	template <typename T, precision P> struct tmat4x4;
 
+	template <typename T, precision P, template <typename, precision> class matType>
+	GLM_FUNC_DECL matType<T, P> inverse(matType<T, P> const & m);
+
 	/// @addtogroup core_precision
 	/// @{
 	

+ 6 - 22
glm/detail/type_mat2x2.inl

@@ -30,26 +30,10 @@
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 
-namespace glm{
-namespace detail
-{
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER tmat2x2<T, P> compute_inverse(tmat2x2<T, P> const & m)
-	{
-		T OneOverDeterminant = static_cast<T>(1) / (
-			+ m[0][0] * m[1][1]
-			- m[1][0] * m[0][1]);
-
-		tmat2x2<T, P> Inverse(
-			+ m[1][1] * OneOverDeterminant,
-			- m[0][1] * OneOverDeterminant,
-			- m[1][0] * OneOverDeterminant,
-			+ m[0][0] * OneOverDeterminant);
-
-		return Inverse;
-	}
-}//namespace detail
+#include "func_matrix.hpp"
 
+namespace glm
+{
 	// -- Constructors --
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
@@ -305,7 +289,7 @@ namespace detail
 	template <typename U>
 	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator/=(tmat2x2<U, P> const & m)
 	{
-		return (*this = *this * detail::compute_inverse<T, P>(m));
+		return *this *= inverse(m);
 	}
 
 	// -- Increment and decrement operators --
@@ -503,13 +487,13 @@ namespace detail
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator/(tmat2x2<T, P> const & m, typename tmat2x2<T, P>::row_type const & v)
 	{
-		return detail::compute_inverse<T, P>(m) * v;
+		return detail::compute_inverse<tmat2x2, T, P>::call(m) * v;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator/(typename tmat2x2<T, P>::col_type const & v, tmat2x2<T, P> const & m)
 	{
-		return v * detail::compute_inverse<T, P>(m);
+		return v * detail::compute_inverse<tmat2x2, T, P>::call(m);
 	}
 
 	template <typename T, precision P>

+ 6 - 28
glm/detail/type_mat3x3.inl

@@ -30,32 +30,10 @@
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 
-namespace glm{
-namespace detail
-{
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER tmat3x3<T, P> compute_inverse(tmat3x3<T, P> const & m)
-	{
-		T OneOverDeterminant = static_cast<T>(1) / (
-			+ 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]));
-
-		tmat3x3<T, P> Inverse(uninitialize);
-		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;
-
-		return Inverse;
-	}
-}//namespace detail
+#include "func_matrix.hpp"
 
+namespace glm
+{
 	// -- Constructors --
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
@@ -351,7 +329,7 @@ namespace detail
 	template <typename U>
 	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator/=(tmat3x3<U, P> const & m)
 	{
-		return (*this = *this * detail::compute_inverse<T, P>(m));
+		return *this *= inverse(m);
 	}
 
 	// -- Increment and decrement operators --
@@ -586,13 +564,13 @@ namespace detail
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::col_type operator/(tmat3x3<T, P> const & m, typename tmat3x3<T, P>::row_type const & v)
 	{
-		return detail::compute_inverse<T, P>(m) * v;
+		return detail::compute_inverse<tmat3x3, T, P>::call(m) * v;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::row_type operator/(typename tmat3x3<T, P>::col_type const & v, tmat3x3<T, P> const & m)
 	{
-		return v * detail::compute_inverse<T, P>(m);
+		return v * detail::compute_inverse<tmat3x3, T, P>::call(m);
 	}
 
 	template <typename T, precision P>

+ 6 - 64
glm/detail/type_mat4x4.inl

@@ -30,68 +30,10 @@
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 
-namespace glm{
-namespace detail
-{
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER tmat4x4<T, P> compute_inverse(tmat4x4<T, P> const & m)
-	{
-		T Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
-		T Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
-		T Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
-
-		T Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
-		T Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
-		T Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
-
-		T Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
-		T Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
-		T Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
-
-		T Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
-		T Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
-		T Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
-
-		T Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
-		T Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
-		T Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
-
-		T Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
-		T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
-		T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
-
-		tvec4<T, P> Fac0(Coef00, Coef00, Coef02, Coef03);
-		tvec4<T, P> Fac1(Coef04, Coef04, Coef06, Coef07);
-		tvec4<T, P> Fac2(Coef08, Coef08, Coef10, Coef11);
-		tvec4<T, P> Fac3(Coef12, Coef12, Coef14, Coef15);
-		tvec4<T, P> Fac4(Coef16, Coef16, Coef18, Coef19);
-		tvec4<T, P> Fac5(Coef20, Coef20, Coef22, Coef23);
-
-		tvec4<T, P> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]);
-		tvec4<T, P> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]);
-		tvec4<T, P> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]);
-		tvec4<T, P> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]);
-
-		tvec4<T, P> Inv0(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
-		tvec4<T, P> Inv1(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
-		tvec4<T, P> Inv2(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
-		tvec4<T, P> Inv3(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
-
-		tvec4<T, P> SignA(+1, -1, +1, -1);
-		tvec4<T, P> SignB(-1, +1, -1, +1);
-		tmat4x4<T, P> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB);
-
-		tvec4<T, P> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
-
-		tvec4<T, P> Dot0(m[0] * Row0);
-		T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w);
-
-		T OneOverDeterminant = static_cast<T>(1) / Dot1;
-
-		return Inverse * OneOverDeterminant;
-	}
-}//namespace detail
+#include "func_matrix.hpp"
 
+namespace glm
+{
 	// -- Constructors --
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
@@ -449,7 +391,7 @@ namespace detail
 	template <typename U>
 	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator/=(tmat4x4<U, P> const & m)
 	{
-		return (*this = *this * detail::compute_inverse<T, P>(m));
+		return *this *= inverse(m);
 	}
 
 	// -- Increment and decrement operators --
@@ -728,13 +670,13 @@ namespace detail
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type operator/(tmat4x4<T, P> const & m, typename tmat4x4<T, P>::row_type const & v)
 	{
-		return detail::compute_inverse<T, P>(m) * v;
+		return detail::compute_inverse<tmat4x4, T, P>::call(m) * v;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::row_type operator/(typename tmat4x4<T, P>::col_type const & v, tmat4x4<T, P> const & m)
 	{
-		return v * detail::compute_inverse<T, P>(m);
+		return v * detail::compute_inverse<tmat4x4, T, P>::call(m);
 	}
 
 	template <typename T, precision P>

+ 8 - 8
glm/detail/type_vec4.hpp

@@ -46,7 +46,7 @@
 namespace glm{
 namespace detail
 {
-	template <typename T, precision P = defaultp>
+	template <typename T>
 	struct simd_data
 	{
 		typedef T type[4];
@@ -54,19 +54,19 @@ namespace detail
 
 #	if (GLM_ARCH & GLM_ARCH_SSE2)
 		template <>
-		struct simd_data<float, simd>
+		struct simd_data<float>
 		{
 			typedef __m128 type;
 		};
 
 		template <>
-		struct simd_data<int, simd>
+		struct simd_data<int>
 		{
 			typedef __m128i type;
 		};
 
 		template <>
-		struct simd_data<unsigned int, simd>
+		struct simd_data<unsigned int>
 		{
 			typedef __m128i type;
 		};
@@ -74,7 +74,7 @@ namespace detail
 
 #	if (GLM_ARCH & GLM_ARCH_AVX)
 		template <>
-		struct simd_data<double, simd>
+		struct simd_data<double>
 		{
 			typedef __m256d type;
 		};
@@ -82,13 +82,13 @@ namespace detail
 
 #	if (GLM_ARCH & GLM_ARCH_AVX2)
 		template <>
-		struct simd_data<int64, simd>
+		struct simd_data<int64>
 		{
 			typedef __m256i type;
 		};
 
 		template <>
-		struct simd_data<uint64, simd>
+		struct simd_data<uint64>
 		{
 			typedef __m256i type;
 		};
@@ -114,7 +114,7 @@ namespace detail
 				struct { T r, g, b, a; };
 				struct { T s, t, p, q; };
 
-				typename detail::simd_data<T, P>::type data;
+				typename detail::simd_data<T>::type data;
 
 #				ifdef GLM_SWIZZLE
 					_GLM_SWIZZLE4_2_MEMBERS(T, P, tvec2, x, y, z, w)

+ 32 - 84
glm/detail/type_vec4.inl

@@ -30,8 +30,19 @@
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 
-namespace glm
+namespace glm{
+namespace detail
 {
+	template <typename T, precision P>
+	struct compute_vec4_add
+	{
+		static tvec4<T, P> call(tvec4<T, P> const & a, tvec4<T, P> const & b)
+		{
+			return tvec4<T, P>(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+		}
+	};
+}//namespace detail
+
 	// -- Implicit basic constructors --
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
@@ -276,10 +287,7 @@ namespace glm
 	template <typename U>
 	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator+=(tvec4<U, P> const & v)
 	{
-		this->x += static_cast<T>(v.x);
-		this->y += static_cast<T>(v.y);
-		this->z += static_cast<T>(v.z);
-		this->w += static_cast<T>(v.w);
+		*this = detail::compute_vec4_add<T, P>::call(*this, tvec4<T, P>(v));
 		return *this;
 	}
 
@@ -633,9 +641,9 @@ namespace glm
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator-(tvec4<T, P> const & v)
 	{
 		return tvec4<T, P>(
-			-v.x, 
-			-v.y, 
-			-v.z, 
+			-v.x,
+			-v.y,
+			-v.z,
 			-v.w);
 	}
 
@@ -644,151 +652,91 @@ namespace glm
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator+(tvec4<T, P> const & v, T scalar)
 	{
-		return tvec4<T, P>(
-			v.x + scalar,
-			v.y + scalar,
-			v.z + scalar,
-			v.w + scalar);
+		return tvec4<T, P>(v) += scalar;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator+(tvec4<T, P> const & v1, tvec1<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x + v2.x,
-			v1.y + v2.x,
-			v1.z + v2.x,
-			v1.w + v2.x);
+		return tvec4<T, P>(v1) += v2;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator+(T scalar, tvec4<T, P> const & v)
 	{
-		return tvec4<T, P>(
-			scalar + v.x,
-			scalar + v.y,
-			scalar + v.z,
-			scalar + v.w);
+		return tvec4<T, P>(v) += scalar;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator+(tvec1<T, P> const & v1, tvec4<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x + v2.x,
-			v1.x + v2.y,
-			v1.x + v2.z,
-			v1.x + v2.w);
+		return tvec4<T, P>(v2) += v1;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator+(tvec4<T, P> const & v1, tvec4<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x + v2.x,
-			v1.y + v2.y,
-			v1.z + v2.z,
-			v1.w + v2.w);
+		return tvec4<T, P>(v1) += v2;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator-(tvec4<T, P> const & v, T scalar)
 	{
-		return tvec4<T, P>(
-			v.x - scalar,
-			v.y - scalar,
-			v.z - scalar,
-			v.w - scalar);
+		return tvec4<T, P>(v) -= scalar;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator-(tvec4<T, P> const & v1, tvec1<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x - v2.x,
-			v1.y - v2.x,
-			v1.z - v2.x,
-			v1.w - v2.x);
+		return tvec4<T, P>(v1) -= v2;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator-(T scalar, tvec4<T, P> const & v)
 	{
-		return tvec4<T, P>(
-			scalar - v.x,
-			scalar - v.y,
-			scalar - v.z,
-			scalar - v.w);
+		return tvec4<T, P>(scalar) -= v;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator-(tvec1<T, P> const & v1, tvec4<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x - v2.x,
-			v1.x - v2.y,
-			v1.x - v2.z,
-			v1.x - v2.w);
+		return tvec4<T, P>(v1) -= v2;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator-(tvec4<T, P> const & v1, tvec4<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x - v2.x,
-			v1.y - v2.y,
-			v1.z - v2.z,
-			v1.w - v2.w);
+		return tvec4<T, P>(v1) -= v2;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator*(tvec4<T, P> const & v, T scalar)
 	{
-		return tvec4<T, P>(
-			v.x * scalar,
-			v.y * scalar,
-			v.z * scalar,
-			v.w * scalar);
+		return tvec4<T, P>(v) *= scalar;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator*(tvec4<T, P> const & v1, tvec1<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x * v2.x,
-			v1.y * v2.x,
-			v1.z * v2.x,
-			v1.w * v2.x);
+		return tvec4<T, P>(v1) *= v2;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator*(T scalar, tvec4<T, P> const & v)
 	{
-		return tvec4<T, P>(
-			scalar * v.x,
-			scalar * v.y,
-			scalar * v.z,
-			scalar * v.w);
+		return tvec4<T, P>(v) *= scalar;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator*(tvec1<T, P> const & v1, tvec4<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x * v2.x,
-			v1.x * v2.y,
-			v1.x * v2.z,
-			v1.x * v2.w);
+		return tvec4<T, P>(v2) *= v1;
 	}
 
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tvec4<T, P> operator*(tvec4<T, P> const & v1, tvec4<T, P> const & v2)
 	{
-		return tvec4<T, P>(
-			v1.x * v2.x,
-			v1.y * v2.y,
-			v1.z * v2.z,
-			v1.w * v2.w);
+		return tvec4<T, P>(v1) *= v2;
 	}
 
 	template <typename T, precision P>
@@ -1180,6 +1128,6 @@ namespace glm
 	}
 }//namespace glm
 
-#if GLM_ARCH != GLM_ARCH_PURE
+#if GLM_ARCH != GLM_ARCH_PURE && GLM_HAS_UNRESTRICTED_UNIONS
 #	include "type_vec4_simd.inl"
 #endif

+ 32 - 67
glm/detail/type_vec4_simd.inl

@@ -1,38 +1,22 @@
-///////////////////////////////////////////////////////////////////////////////////
-/// OpenGL Mathematics (glm.g-truc.net)
-///
-/// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
-/// Permission is hereby granted, free of charge, to any person obtaining a copy
-/// of this software and associated documentation files (the "Software"), to deal
-/// in the Software without restriction, including without limitation the rights
-/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-/// copies of the Software, and to permit persons to whom the Software is
-/// furnished to do so, subject to the following conditions:
-/// 
-/// The above copyright notice and this permission notice shall be included in
-/// all copies or substantial portions of the Software.
-/// 
-/// Restrictions:
-///		By making use of the Software for military purposes, you choose to make
-///		a Bunny unhappy.
-/// 
-/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-/// THE SOFTWARE.
-///
 /// @ref core
 /// @file glm/detail/type_tvec4_sse2.inl
-/// @date 2014-12-01 / 2014-12-01
-/// @author Christophe Riccio
-///////////////////////////////////////////////////////////////////////////////////
 
-namespace glm
+#if GLM_ARCH & GLM_ARCH_SSE2
+
+namespace glm{
+namespace detail
 {
-#	if GLM_HAS_UNRESTRICTED_UNIONS
+	template <precision P>
+	struct compute_vec4_add<float, P>
+	{
+		static tvec4<float, P> call(tvec4<float, P> const & a, tvec4<float, P> const & b)
+		{
+			tvec4<float, P> Result(uninitialize);
+			Result.data = _mm_add_ps(a.data, b.data);
+			return Result;
+		}
+	};
+}//namespace detail
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template <>
@@ -44,53 +28,34 @@ namespace glm
 #	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
 
 	template <>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, simd>::tvec4(float s) :
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, lowp>::tvec4(float s) :
 		data(_mm_set1_ps(s))
 	{}
 
 	template <>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, simd>::tvec4(float a, float b, float c, float d) :
-		data(_mm_set_ps(d, c, b, a))
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, mediump>::tvec4(float s) :
+		data(_mm_set1_ps(s))
 	{}
 
 	template <>
-	template <typename U>
-	GLM_FUNC_QUALIFIER tvec4<float, simd> & tvec4<float, simd>::operator+=(U scalar)
-	{
-		this->data = _mm_add_ps(this->data, _mm_set_ps1(static_cast<float>(scalar)));
-		return *this;
-	}
-
-	template <>
-	template <>
-	GLM_FUNC_QUALIFIER tvec4<float, simd> & tvec4<float, simd>::operator+=<float>(float scalar)
-	{
-		this->data = _mm_add_ps(this->data, _mm_set_ps1(scalar));
-		return *this;
-	}
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, highp>::tvec4(float s) :
+		data(_mm_set1_ps(s))
+	{}
 
 	template <>
-	template <typename U>
-	GLM_FUNC_QUALIFIER tvec4<float, simd> & tvec4<float, simd>::operator+=(tvec1<U, simd> const & v)
-	{
-		this->data = _mm_add_ps(this->data, _mm_set_ps1(static_cast<float>(v.x)));
-		return *this;
-	}
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, lowp>::tvec4(float a, float b, float c, float d) :
+		data(_mm_set_ps(d, c, b, a))
+	{}
 
 	template <>
-	GLM_FUNC_QUALIFIER tvec4<float, simd> operator+(tvec4<float, simd> const & v1, tvec4<float, simd> const & v2)
-	{
-		tvec4<float, glm::simd> Result(uninitialize);
-		Result.data = _mm_add_ps(v1.data, v2.data);
-		return Result;
-	}
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, mediump>::tvec4(float a, float b, float c, float d) :
+		data(_mm_set_ps(d, c, b, a))
+	{}
 
 	template <>
-	GLM_FUNC_QUALIFIER tvec4<float, simd> operator*(tvec4<float, simd> const & v1, tvec4<float, simd> const & v2)
-	{
-		tvec4<float, glm::simd> Result(uninitialize);
-		Result.data = _mm_mul_ps(v1.data, v2.data);
-		return Result;
-	}
-#endif//GLM_HAS_UNRESTRICTED_UNIONS
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, highp>::tvec4(float a, float b, float c, float d) :
+		data(_mm_set_ps(d, c, b, a))
+	{}
 }//namespace glm
+
+#endif//GLM_ARCH & GLM_ARCH_SSE2

+ 14 - 14
test/core/core_func_matrix.cpp

@@ -219,24 +219,24 @@ int test_inverse()
 
 int test_inverse_simd()
 {
-	int Failed(0);
+	int Error = 0;
 
-	glm::tmat4x4<float, glm::simd> const Identity(1);
+	glm::mat4x4 const Identity(1);
 
-	glm::tmat4x4<float, glm::simd> const A4x4(
-		glm::tvec4<float, glm::simd>(1, 0, 1, 0),
-		glm::tvec4<float, glm::simd>(0, 1, 0, 0),
-		glm::tvec4<float, glm::simd>(0, 0, 1, 0),
-		glm::tvec4<float, glm::simd>(0, 0, 0, 1));
-	glm::tmat4x4<float, glm::simd> const B4x4 = glm::inverse(A4x4);
-	glm::tmat4x4<float, glm::simd> const I4x4 = A4x4 * B4x4;
+	glm::mat4x4 const A4x4(
+		glm::vec4(1, 0, 1, 0),
+		glm::vec4(0, 1, 0, 0),
+		glm::vec4(0, 0, 1, 0),
+		glm::vec4(0, 0, 0, 1));
+	glm::mat4x4 const B4x4 = glm::inverse(A4x4);
+	glm::mat4x4 const I4x4 = A4x4 * B4x4;
 
-	Failed += glm::all(glm::epsilonEqual(I4x4[0], Identity[0], 0.001f)) ? 0 : 1;
-	Failed += glm::all(glm::epsilonEqual(I4x4[1], Identity[1], 0.001f)) ? 0 : 1;
-	Failed += glm::all(glm::epsilonEqual(I4x4[2], Identity[2], 0.001f)) ? 0 : 1;
-	Failed += glm::all(glm::epsilonEqual(I4x4[3], Identity[3], 0.001f)) ? 0 : 1;
+	Error += glm::all(glm::epsilonEqual(I4x4[0], Identity[0], 0.001f)) ? 0 : 1;
+	Error += glm::all(glm::epsilonEqual(I4x4[1], Identity[1], 0.001f)) ? 0 : 1;
+	Error += glm::all(glm::epsilonEqual(I4x4[2], Identity[2], 0.001f)) ? 0 : 1;
+	Error += glm::all(glm::epsilonEqual(I4x4[3], Identity[3], 0.001f)) ? 0 : 1;
 
-	return Failed;
+	return Error;
 }
 
 template <typename VEC3, typename MAT4>

+ 5 - 5
test/core/core_type_vec4.cpp

@@ -488,13 +488,13 @@ int test_vec4_simd()
 {
 	int Error = 0;
 
-	glm::tvec4<float, glm::simd> a(std::clock(), std::clock(), std::clock(), std::clock());
-	glm::tvec4<float, glm::simd> b(std::clock(), std::clock(), std::clock(), std::clock());
+	glm::vec4 const a(std::clock(), std::clock(), std::clock(), std::clock());
+	glm::vec4 const b(std::clock(), std::clock(), std::clock(), std::clock());
 
-	glm::tvec4<float, glm::simd> c(b * a);
-	glm::tvec4<float, glm::simd> d(a + c);
+	glm::vec4 const c(b * a);
+	glm::vec4 const d(a + c);
 
-	Error += glm::all(glm::greaterThanEqual(d, glm::tvec4<float, glm::simd>(0))) ? 0 : 1;
+	Error += glm::all(glm::greaterThanEqual(d, glm::vec4(0))) ? 0 : 1;
 
 	return Error;
 }