diff --git a/glm/detail/func_common.inl b/glm/detail/func_common.inl index 5037fd5e..e505137f 100644 --- a/glm/detail/func_common.inl +++ b/glm/detail/func_common.inl @@ -52,7 +52,16 @@ namespace detail } }; - template class vecType> + template class vecType> + struct compute_abs_vector + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(abs, x); + } + }; + + template class vecType> struct compute_mix_vector { GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, vecType const & a) @@ -63,7 +72,7 @@ namespace detail } }; - template class vecType> + template class vecType> struct compute_mix_vector { GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, vecType const & a) @@ -75,7 +84,7 @@ namespace detail } }; - template class vecType> + template class vecType> struct compute_mix_scalar { GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, U const & a) @@ -86,7 +95,7 @@ namespace detail } }; - template class vecType> + template class vecType> struct compute_mix_scalar { GLM_FUNC_QUALIFIER static vecType call(vecType const & x, vecType const & y, bool const & a) @@ -115,7 +124,7 @@ namespace detail } }; - template class vecType, bool isFloat = true> + template class vecType, bool isFloat = true> struct compute_sign { GLM_FUNC_QUALIFIER static vecType call(vecType const & x) @@ -125,7 +134,7 @@ namespace detail }; # if GLM_ARCH == GLM_ARCH_X86 - template class vecType> + template class vecType> struct compute_sign { GLM_FUNC_QUALIFIER static vecType call(vecType const & x) @@ -138,10 +147,55 @@ namespace detail }; # endif - template class vecType, typename genType, bool isFloat = true> + template class vecType> + struct compute_floor + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(floor, x); + } + }; + + template class vecType> + struct compute_ceil + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(ceil, x); + } + }; + + template class vecType> + struct compute_fract + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return x - floor(x); + } + }; + + template class vecType> + struct compute_trunc + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(trunc, x); + } + }; + + template class vecType> + struct compute_round + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return detail::functor1::call(round, x); + } + }; + + template class vecType> struct compute_mod { - GLM_FUNC_QUALIFIER static vecType call(vecType const & a, genType const & b) + GLM_FUNC_QUALIFIER static vecType call(vecType const & a, vecType const & b) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'mod' only accept floating-point inputs. Include for integer inputs."); return a - b * floor(a / b); @@ -166,7 +220,7 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType abs(vecType const & x) { - return detail::functor1::call(abs, x); + return detail::compute_abs_vector::call(x); } // sign @@ -196,7 +250,8 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType floor(vecType const & x) { - return detail::functor1::call(floor, x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'floor' only accept floating-point inputs."); + return detail::compute_floor::call(x); } // trunc @@ -215,7 +270,8 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType trunc(vecType const & x) { - return detail::functor1::call(trunc, x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'trunc' only accept floating-point inputs"); + return detail::compute_trunc::call(x); } // round @@ -234,7 +290,8 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType round(vecType const & x) { - return detail::functor1::call(round, x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'round' only accept floating-point inputs"); + return detail::compute_round::call(x); } /* @@ -283,6 +340,7 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType roundEven(vecType const & x) { + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'roundEven' only accept floating-point inputs"); return detail::functor1::call(roundEven, x); } @@ -291,22 +349,22 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType ceil(vecType const & x) { - return detail::functor1::call(ceil, x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'ceil' only accept floating-point inputs"); + return detail::compute_ceil::call(x); } // fract template GLM_FUNC_QUALIFIER genType fract(genType x) { - GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fract' only accept floating-point inputs"); - return fract(tvec1(x)).x; } template class vecType> GLM_FUNC_QUALIFIER vecType fract(vecType const & x) { - return x - floor(x); + GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'fract' only accept floating-point inputs"); + return detail::compute_fract::call(x); } // mod @@ -319,13 +377,13 @@ namespace detail template class vecType> GLM_FUNC_QUALIFIER vecType mod(vecType const & x, T y) { - return detail::compute_mod::is_iec559>::call(x, y); + return detail::compute_mod::call(x, vecType(y)); } template class vecType> GLM_FUNC_QUALIFIER vecType mod(vecType const & x, vecType const & y) { - return detail::compute_mod, std::numeric_limits::is_iec559>::call(x, y); + return detail::compute_mod::call(x, y); } // modf @@ -333,7 +391,6 @@ namespace detail GLM_FUNC_QUALIFIER genType modf(genType x, genType & i) { GLM_STATIC_ASSERT(std::numeric_limits::is_iec559, "'modf' only accept floating-point inputs"); - return std::modf(x, &i); } diff --git a/glm/detail/func_common_simd.inl b/glm/detail/func_common_simd.inl index 6ff5e241..0bcd6c4a 100644 --- a/glm/detail/func_common_simd.inl +++ b/glm/detail/func_common_simd.inl @@ -10,6 +10,28 @@ namespace glm{ namespace detail { + template + struct compute_abs_vector + { + GLM_FUNC_QUALIFIER static tvec4 call(tvec4 const & v) + { + tvec4 result(uninitialize); + result.data = glm_f32v4_abs(v.data); + return result; + } + }; + + template + struct compute_abs_vector + { + GLM_FUNC_QUALIFIER static tvec4 call(tvec4 const & v) + { + tvec4 result(uninitialize); + result.data = glm_i32v4_abs(v.data); + return result; + } + }; + template struct compute_mix_vector { @@ -28,109 +50,60 @@ namespace detail } }; -/* - static const __m128 GLM_VAR_USED zero = _mm_setzero_ps(); - static const __m128 GLM_VAR_USED one = _mm_set_ps1(1.0f); - static const __m128 GLM_VAR_USED minus_one = _mm_set_ps1(-1.0f); - static const __m128 GLM_VAR_USED two = _mm_set_ps1(2.0f); - static const __m128 GLM_VAR_USED three = _mm_set_ps1(3.0f); - static const __m128 GLM_VAR_USED pi = _mm_set_ps1(3.1415926535897932384626433832795f); - static const __m128 GLM_VAR_USED hundred_eighty = _mm_set_ps1(180.f); - static const __m128 GLM_VAR_USED pi_over_hundred_eighty = _mm_set_ps1(0.017453292519943295769236907684886f); - static const __m128 GLM_VAR_USED hundred_eighty_over_pi = _mm_set_ps1(57.295779513082320876798154814105f); + template + struct compute_floor + { + GLM_FUNC_QUALIFIER static tvec4 call(tvec4 const & v) + { + tvec4 result(uninitialize); + result.data = glm_f32v4_flr(v.data); + return result; + } + }; - static const ieee754_QNAN absMask; - static const __m128 GLM_VAR_USED abs4Mask = _mm_set_ps1(absMask.f); + template + struct compute_ceil + { + GLM_FUNC_QUALIFIER static tvec4 call(tvec4 const & v) + { + tvec4 result(uninitialize); + result.data = glm_f32v4_ceil(v.data); + return result; + } + }; - static const __m128 GLM_VAR_USED _epi32_sign_mask = _mm_castsi128_ps(_mm_set1_epi32(static_cast(0x80000000))); - //static const __m128 GLM_VAR_USED _epi32_inv_sign_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7FFFFFFF)); - //static const __m128 GLM_VAR_USED _epi32_mant_mask = _mm_castsi128_ps(_mm_set1_epi32(0x7F800000)); - //static const __m128 GLM_VAR_USED _epi32_inv_mant_mask = _mm_castsi128_ps(_mm_set1_epi32(0x807FFFFF)); - //static const __m128 GLM_VAR_USED _epi32_min_norm_pos = _mm_castsi128_ps(_mm_set1_epi32(0x00800000)); - static const __m128 GLM_VAR_USED _epi32_0 = _mm_set_ps1(0); - static const __m128 GLM_VAR_USED _epi32_1 = _mm_set_ps1(1); - static const __m128 GLM_VAR_USED _epi32_2 = _mm_set_ps1(2); - static const __m128 GLM_VAR_USED _epi32_3 = _mm_set_ps1(3); - static const __m128 GLM_VAR_USED _epi32_4 = _mm_set_ps1(4); - static const __m128 GLM_VAR_USED _epi32_5 = _mm_set_ps1(5); - static const __m128 GLM_VAR_USED _epi32_6 = _mm_set_ps1(6); - static const __m128 GLM_VAR_USED _epi32_7 = _mm_set_ps1(7); - static const __m128 GLM_VAR_USED _epi32_8 = _mm_set_ps1(8); - static const __m128 GLM_VAR_USED _epi32_9 = _mm_set_ps1(9); - static const __m128 GLM_VAR_USED _epi32_127 = _mm_set_ps1(127); - //static const __m128 GLM_VAR_USED _epi32_ninf = _mm_castsi128_ps(_mm_set1_epi32(0xFF800000)); - //static const __m128 GLM_VAR_USED _epi32_pinf = _mm_castsi128_ps(_mm_set1_epi32(0x7F800000)); + template + struct compute_fract + { + GLM_FUNC_QUALIFIER static tvec4 call(tvec4 const & v) + { + tvec4 result(uninitialize); + result.data = glm_f32v4_frc(v.data); + return result; + } + }; - static const __m128 GLM_VAR_USED _ps_1_3 = _mm_set_ps1(0.33333333333333333333333333333333f); - static const __m128 GLM_VAR_USED _ps_0p5 = _mm_set_ps1(0.5f); - static const __m128 GLM_VAR_USED _ps_1 = _mm_set_ps1(1.0f); - static const __m128 GLM_VAR_USED _ps_m1 = _mm_set_ps1(-1.0f); - static const __m128 GLM_VAR_USED _ps_2 = _mm_set_ps1(2.0f); - static const __m128 GLM_VAR_USED _ps_3 = _mm_set_ps1(3.0f); - static const __m128 GLM_VAR_USED _ps_127 = _mm_set_ps1(127.0f); - static const __m128 GLM_VAR_USED _ps_255 = _mm_set_ps1(255.0f); - static const __m128 GLM_VAR_USED _ps_2pow23 = _mm_set_ps1(8388608.0f); + template + struct compute_round + { + GLM_FUNC_QUALIFIER static tvec4 call(tvec4 const & v) + { + tvec4 result(uninitialize); + result.data = glm_f32v4_rnd(v.data); + return result; + } + }; - static const __m128 GLM_VAR_USED _ps_1_0_0_0 = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f); - static const __m128 GLM_VAR_USED _ps_0_1_0_0 = _mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f); - static const __m128 GLM_VAR_USED _ps_0_0_1_0 = _mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f); - static const __m128 GLM_VAR_USED _ps_0_0_0_1 = _mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f); - - static const __m128 GLM_VAR_USED _ps_pi = _mm_set_ps1(3.1415926535897932384626433832795f); - static const __m128 GLM_VAR_USED _ps_pi2 = _mm_set_ps1(6.283185307179586476925286766560f); - static const __m128 GLM_VAR_USED _ps_2_pi = _mm_set_ps1(0.63661977236758134307553505349006f); - static const __m128 GLM_VAR_USED _ps_pi_2 = _mm_set_ps1(1.5707963267948966192313216916398f); - static const __m128 GLM_VAR_USED _ps_4_pi = _mm_set_ps1(1.2732395447351626861510701069801f); - static const __m128 GLM_VAR_USED _ps_pi_4 = _mm_set_ps1(0.78539816339744830961566084581988f); - - static const __m128 GLM_VAR_USED _ps_sincos_p0 = _mm_set_ps1(0.15707963267948963959e1f); - static const __m128 GLM_VAR_USED _ps_sincos_p1 = _mm_set_ps1(-0.64596409750621907082e0f); - static const __m128 GLM_VAR_USED _ps_sincos_p2 = _mm_set_ps1(0.7969262624561800806e-1f); - static const __m128 GLM_VAR_USED _ps_sincos_p3 = _mm_set_ps1(-0.468175413106023168e-2f); - static const __m128 GLM_VAR_USED _ps_tan_p0 = _mm_set_ps1(-1.79565251976484877988e7f); - static const __m128 GLM_VAR_USED _ps_tan_p1 = _mm_set_ps1(1.15351664838587416140e6f); - static const __m128 GLM_VAR_USED _ps_tan_p2 = _mm_set_ps1(-1.30936939181383777646e4f); - static const __m128 GLM_VAR_USED _ps_tan_q0 = _mm_set_ps1(-5.38695755929454629881e7f); - static const __m128 GLM_VAR_USED _ps_tan_q1 = _mm_set_ps1(2.50083801823357915839e7f); - static const __m128 GLM_VAR_USED _ps_tan_q2 = _mm_set_ps1(-1.32089234440210967447e6f); - static const __m128 GLM_VAR_USED _ps_tan_q3 = _mm_set_ps1(1.36812963470692954678e4f); - static const __m128 GLM_VAR_USED _ps_tan_poleval = _mm_set_ps1(3.68935e19f); - static const __m128 GLM_VAR_USED _ps_atan_t0 = _mm_set_ps1(-0.91646118527267623468e-1f); - static const __m128 GLM_VAR_USED _ps_atan_t1 = _mm_set_ps1(-0.13956945682312098640e1f); - static const __m128 GLM_VAR_USED _ps_atan_t2 = _mm_set_ps1(-0.94393926122725531747e2f); - static const __m128 GLM_VAR_USED _ps_atan_t3 = _mm_set_ps1(0.12888383034157279340e2f); - static const __m128 GLM_VAR_USED _ps_atan_s0 = _mm_set_ps1(0.12797564625607904396e1f); - static const __m128 GLM_VAR_USED _ps_atan_s1 = _mm_set_ps1(0.21972168858277355914e1f); - static const __m128 GLM_VAR_USED _ps_atan_s2 = _mm_set_ps1(0.68193064729268275701e1f); - static const __m128 GLM_VAR_USED _ps_atan_s3 = _mm_set_ps1(0.28205206687035841409e2f); - - static const __m128 GLM_VAR_USED _ps_exp_hi = _mm_set_ps1(88.3762626647949f); - static const __m128 GLM_VAR_USED _ps_exp_lo = _mm_set_ps1(-88.3762626647949f); - static const __m128 GLM_VAR_USED _ps_exp_rln2 = _mm_set_ps1(1.4426950408889634073599f); - static const __m128 GLM_VAR_USED _ps_exp_p0 = _mm_set_ps1(1.26177193074810590878e-4f); - static const __m128 GLM_VAR_USED _ps_exp_p1 = _mm_set_ps1(3.02994407707441961300e-2f); - static const __m128 GLM_VAR_USED _ps_exp_q0 = _mm_set_ps1(3.00198505138664455042e-6f); - static const __m128 GLM_VAR_USED _ps_exp_q1 = _mm_set_ps1(2.52448340349684104192e-3f); - static const __m128 GLM_VAR_USED _ps_exp_q2 = _mm_set_ps1(2.27265548208155028766e-1f); - static const __m128 GLM_VAR_USED _ps_exp_q3 = _mm_set_ps1(2.00000000000000000009e0f); - static const __m128 GLM_VAR_USED _ps_exp_c1 = _mm_set_ps1(6.93145751953125e-1f); - static const __m128 GLM_VAR_USED _ps_exp_c2 = _mm_set_ps1(1.42860682030941723212e-6f); - static const __m128 GLM_VAR_USED _ps_exp2_hi = _mm_set_ps1(127.4999961853f); - static const __m128 GLM_VAR_USED _ps_exp2_lo = _mm_set_ps1(-127.4999961853f); - static const __m128 GLM_VAR_USED _ps_exp2_p0 = _mm_set_ps1(2.30933477057345225087e-2f); - static const __m128 GLM_VAR_USED _ps_exp2_p1 = _mm_set_ps1(2.02020656693165307700e1f); - static const __m128 GLM_VAR_USED _ps_exp2_p2 = _mm_set_ps1(1.51390680115615096133e3f); - static const __m128 GLM_VAR_USED _ps_exp2_q0 = _mm_set_ps1(2.33184211722314911771e2f); - static const __m128 GLM_VAR_USED _ps_exp2_q1 = _mm_set_ps1(4.36821166879210612817e3f); - static const __m128 GLM_VAR_USED _ps_log_p0 = _mm_set_ps1(-7.89580278884799154124e-1f); - static const __m128 GLM_VAR_USED _ps_log_p1 = _mm_set_ps1(1.63866645699558079767e1f); - static const __m128 GLM_VAR_USED _ps_log_p2 = _mm_set_ps1(-6.41409952958715622951e1f); - static const __m128 GLM_VAR_USED _ps_log_q0 = _mm_set_ps1(-3.56722798256324312549e1f); - static const __m128 GLM_VAR_USED _ps_log_q1 = _mm_set_ps1(3.12093766372244180303e2f); - static const __m128 GLM_VAR_USED _ps_log_q2 = _mm_set_ps1(-7.69691943550460008604e2f); - static const __m128 GLM_VAR_USED _ps_log_c0 = _mm_set_ps1(0.693147180559945f); - static const __m128 GLM_VAR_USED _ps_log2_c0 = _mm_set_ps1(1.44269504088896340735992f); -*/ + template + struct compute_mod + { + GLM_FUNC_QUALIFIER static tvec4 call(tvec4 const & x, tvec4 const & y) + { + tvec4 result(uninitialize); + result.data = glm_f32v4_mod(x.data, y.data); + return result; + } + }; }//namespace detail }//namespace glm diff --git a/glm/simd/common.h b/glm/simd/common.h index 90cb5cf4..2e1f2150 100644 --- a/glm/simd/common.h +++ b/glm/simd/common.h @@ -60,29 +60,37 @@ GLM_FUNC_QUALIFIER __m128 glm_f32v4_sgn(__m128 x) //round GLM_FUNC_QUALIFIER __m128 glm_f32v4_rnd(__m128 x) { - __m128 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); - __m128 const and0 = _mm_and_ps(sgn0, x); - __m128 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f)); - __m128 const add0 = _mm_add_ps(x, or0); - __m128 const sub0 = _mm_sub_ps(add0, or0); - return sub0; +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_round_ps(x, _MM_FROUND_TO_NEAREST_INT); +# else + __m128 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); + __m128 const and0 = _mm_and_ps(sgn0, x); + __m128 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f)); + __m128 const add0 = _mm_add_ps(x, or0); + __m128 const sub0 = _mm_sub_ps(add0, or0); + return sub0; +# endif } //floor GLM_FUNC_QUALIFIER __m128 glm_f32v4_flr(__m128 x) { - __m128 const rnd0 = glm_f32v4_rnd(x); - __m128 const cmp0 = _mm_cmplt_ps(x, rnd0); - __m128 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); - __m128 const sub0 = _mm_sub_ps(rnd0, and0); - return sub0; +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_floor_ps(x); +# else + __m128 const rnd0 = glm_f32v4_rnd(x); + __m128 const cmp0 = _mm_cmplt_ps(x, rnd0); + __m128 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); + __m128 const sub0 = _mm_sub_ps(rnd0, and0); + return sub0; +# endif } //trunc -//GLM_FUNC_QUALIFIER __m128 _mm_trc_ps(__m128 v) -//{ -// return __m128(); -//} +GLM_FUNC_QUALIFIER __m128 glm_f32v4_trc(__m128 x) +{ + return __m128(); +} //roundEven GLM_FUNC_QUALIFIER __m128 glm_f32v4_rde(__m128 x) @@ -97,11 +105,15 @@ GLM_FUNC_QUALIFIER __m128 glm_f32v4_rde(__m128 x) GLM_FUNC_QUALIFIER __m128 glm_f32v4_ceil(__m128 x) { - __m128 const rnd0 = glm_f32v4_rnd(x); - __m128 const cmp0 = _mm_cmpgt_ps(x, rnd0); - __m128 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); - __m128 const add0 = _mm_add_ps(rnd0, and0); - return add0; +# if GLM_ARCH & GLM_ARCH_SSE41_BIT + return _mm_ceil_ps(x); +# else + __m128 const rnd0 = glm_f32v4_rnd(x); + __m128 const cmp0 = _mm_cmpgt_ps(x, rnd0); + __m128 const and0 = _mm_and_ps(cmp0, _mm_set1_ps(1.0f)); + __m128 const add0 = _mm_add_ps(rnd0, and0); + return add0; +# endif } GLM_FUNC_QUALIFIER __m128 glm_f32v4_frc(__m128 x)