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

This commit is contained in:
Christophe Riccio 2016-05-22 17:12:32 +02:00
parent 805939686c
commit 757fe39587
15 changed files with 251 additions and 327 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

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

View file

@ -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

View file

@ -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
/// @{

View file

@ -30,26 +30,10 @@
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail
#include "func_matrix.hpp"
namespace glm
{
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
// -- 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>

View file

@ -30,32 +30,10 @@
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail
#include "func_matrix.hpp"
namespace glm
{
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
// -- 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>

View file

@ -30,68 +30,10 @@
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail
#include "func_matrix.hpp"
namespace glm
{
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
// -- 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>

View file

@ -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)

View file

@ -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

View file

@ -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) :
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, mediump>::tvec4(float s) :
data(_mm_set1_ps(s))
{}
template <>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD tvec4<float, highp>::tvec4(float s) :
data(_mm_set1_ps(s))
{}
template <>
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 <>
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;
}
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 <>
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;
}
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;
}
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;
}
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

View file

@ -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>

View file

@ -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;
}