From d4046da22e07a47a5f7e700946700397ec4c414f Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Thu, 10 Oct 2013 00:51:29 +0200 Subject: [PATCH] Fixed umulExtended and imulExtended implementations for vector types (#76) --- glm/core/func_integer.inl | 182 ++++++++++++++++++++------------------ readme.txt | 1 + 2 files changed, 97 insertions(+), 86 deletions(-) diff --git a/glm/core/func_integer.inl b/glm/core/func_integer.inl index a23401b1..78f2ca11 100644 --- a/glm/core/func_integer.inl +++ b/glm/core/func_integer.inl @@ -50,9 +50,11 @@ namespace glm genUType & Carry ) { - detail::highp_uint_t Value64 = detail::highp_uint_t(x) + detail::highp_uint_t(y); - genUType Result = genUType(Value64 % (detail::highp_uint_t(1) << detail::highp_uint_t(32))); - Carry = (Value64 % (detail::highp_uint_t(1) << detail::highp_uint_t(32))) > 1 ? 1 : 0; + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'uaddCarry' only accept unsigned integer inputs"); + + uint64 Value64 = static_cast(x) + static_cast(y); + genUType Result = genUType(Value64 % (static_cast(1) << static_cast(32))); + Carry = (Value64 % (static_cast(1) << static_cast(32))) > 1 ? static_cast(1) : static_cast(0); return Result; } @@ -64,6 +66,8 @@ namespace glm detail::tvec2 & Carry ) { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'uaddCarry' only accept unsigned integer inputs"); + return detail::tvec2( uaddCarry(x[0], y[0], Carry[0]), uaddCarry(x[1], y[1], Carry[1])); @@ -77,6 +81,8 @@ namespace glm detail::tvec3 & Carry ) { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'uaddCarry' only accept unsigned integer inputs"); + return detail::tvec3( uaddCarry(x[0], y[0], Carry[0]), uaddCarry(x[1], y[1], Carry[1]), @@ -91,6 +97,8 @@ namespace glm detail::tvec4 & Carry ) { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'uaddCarry' only accept unsigned integer inputs"); + return detail::tvec4( uaddCarry(x[0], y[0], Carry[0]), uaddCarry(x[1], y[1], Carry[1]), @@ -107,11 +115,13 @@ namespace glm genUType & Borrow ) { - Borrow = x >= y ? 0 : 1; + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'usubBorrow' only accept unsigned integer inputs"); + + Borrow = x >= y ? static_cast(0) : static_cast(1); if(x > y) - return genUType(detail::highp_int_t(x) - detail::highp_int_t(y)); + return static_cast(static_cast(x) -static_cast(y)); else - return genUType((detail::highp_int_t(1) << detail::highp_int_t(32)) + detail::highp_int_t(x) - detail::highp_int_t(y)); + return static_cast((static_cast(1) << static_cast(32)) + static_cast(x) - static_cast(y)); } template @@ -122,6 +132,8 @@ namespace glm detail::tvec2 & Borrow ) { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'usubBorrow' only accept unsigned integer inputs"); + return detail::tvec2( usubBorrow(x[0], y[0], Borrow[0]), usubBorrow(x[1], y[1], Borrow[1])); @@ -135,6 +147,8 @@ namespace glm detail::tvec3 & Borrow ) { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'usubBorrow' only accept unsigned integer inputs"); + return detail::tvec3( usubBorrow(x[0], y[0], Borrow[0]), usubBorrow(x[1], y[1], Borrow[1]), @@ -149,6 +163,8 @@ namespace glm detail::tvec4 & Borrow ) { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "'usubBorrow' only accept unsigned integer inputs"); + return detail::tvec4( usubBorrow(x[0], y[0], Borrow[0]), usubBorrow(x[1], y[1], Borrow[1]), @@ -157,127 +173,121 @@ namespace glm } // umulExtended - template + template <> GLM_FUNC_QUALIFIER void umulExtended ( - genUType const & x, - genUType const & y, - genUType & msb, - genUType & lsb + uint const & x, + uint const & y, + uint & msb, + uint & lsb ) { - detail::highp_uint_t ValueX64 = x; - detail::highp_uint_t ValueY64 = y; - detail::highp_uint_t Value64 = ValueX64 * ValueY64; - msb = *(genUType*)&genUType(Value64 & ((detail::highp_uint_t(1) << detail::highp_uint_t(32)) - detail::highp_uint_t(1))); - lsb = *(genUType*)&genUType(Value64 >> detail::highp_uint_t(32)); + GLM_STATIC_ASSERT(sizeof(uint) == sizeof(uint32), "uint and uint32 size mismatch"); + + uint64 Value64 = static_cast(x) * static_cast(y); + msb = *(reinterpret_cast(&Value64) + 1); + lsb = reinterpret_cast(Value64); } - template - GLM_FUNC_QUALIFIER detail::tvec2 umulExtended + template <> + GLM_FUNC_QUALIFIER void umulExtended ( - detail::tvec2 const & x, - detail::tvec2 const & y, - detail::tvec2 & msb, - detail::tvec2 & lsb + uvec2 const & x, + uvec2 const & y, + uvec2 & msb, + uvec2 & lsb ) { - return detail::tvec2( - umulExtended(x[0], y[0], msb, lsb), - umulExtended(x[1], y[1], msb, lsb)); + umulExtended(x[0], y[0], msb[0], lsb[0]); + umulExtended(x[1], y[1], msb[1], lsb[1]); } - template - GLM_FUNC_QUALIFIER detail::tvec3 umulExtended + template <> + GLM_FUNC_QUALIFIER void umulExtended ( - detail::tvec3 const & x, - detail::tvec3 const & y, - detail::tvec3 & msb, - detail::tvec3 & lsb + uvec3 const & x, + uvec3 const & y, + uvec3 & msb, + uvec3 & lsb ) { - return detail::tvec3( - umulExtended(x[0], y[0], msb, lsb), - umulExtended(x[1], y[1], msb, lsb), - umulExtended(x[2], y[2], msb, lsb)); + umulExtended(x[0], y[0], msb[0], lsb[0]); + umulExtended(x[1], y[1], msb[1], lsb[1]); + umulExtended(x[2], y[2], msb[2], lsb[2]); } - template - GLM_FUNC_QUALIFIER detail::tvec4 umulExtended + template <> + GLM_FUNC_QUALIFIER void umulExtended ( - detail::tvec4 const & x, - detail::tvec4 const & y, - detail::tvec4 & msb, - detail::tvec4 & lsb + uvec4 const & x, + uvec4 const & y, + uvec4 & msb, + uvec4 & lsb ) { - return detail::tvec4( - umulExtended(x[0], y[0], msb, lsb), - umulExtended(x[1], y[1], msb, lsb), - umulExtended(x[2], y[2], msb, lsb), - umulExtended(x[3], y[3], msb, lsb)); + umulExtended(x[0], y[0], msb[0], lsb[0]); + umulExtended(x[1], y[1], msb[1], lsb[1]); + umulExtended(x[2], y[2], msb[2], lsb[2]); + umulExtended(x[3], y[3], msb[3], lsb[3]); } // imulExtended - template + template <> GLM_FUNC_QUALIFIER void imulExtended ( - genIType const & x, - genIType const & y, - genIType & msb, - genIType & lsb + int const & x, + int const & y, + int & msb, + int & lsb ) { - detail::highp_int_t ValueX64 = x; - detail::highp_int_t ValueY64 = y; - detail::highp_int_t Value64 = ValueX64 * ValueY64; - msb = *(genIType*)&genIType(Value64 & ((detail::highp_uint_t(1) << detail::highp_uint_t(32)) - detail::highp_uint_t(1))); - lsb = *(genIType*)&genIType(Value64 >> detail::highp_uint_t(32)); + GLM_STATIC_ASSERT(sizeof(int) == sizeof(int32), "int and int32 size mismatch"); + + int64 Value64 = static_cast(x) * static_cast(y); + msb = *(reinterpret_cast(&Value64) + 1); + lsb = reinterpret_cast(Value64); } - template - GLM_FUNC_QUALIFIER detail::tvec2 imulExtended + template <> + GLM_FUNC_QUALIFIER void imulExtended ( - detail::tvec2 const & x, - detail::tvec2 const & y, - detail::tvec2 & msb, - detail::tvec2 & lsb + ivec2 const & x, + ivec2 const & y, + ivec2 & msb, + ivec2 & lsb ) { - return detail::tvec2( - imulExtended(x[0], y[0], msb, lsb), - imulExtended(x[1], y[1], msb, lsb)); + imulExtended(x[0], y[0], msb[0], lsb[0]), + imulExtended(x[1], y[1], msb[1], lsb[1]); } - template - GLM_FUNC_QUALIFIER detail::tvec3 imulExtended + template <> + GLM_FUNC_QUALIFIER void imulExtended ( - detail::tvec3 const & x, - detail::tvec3 const & y, - detail::tvec3 & msb, - detail::tvec3 & lsb + ivec3 const & x, + ivec3 const & y, + ivec3 & msb, + ivec3 & lsb ) { - return detail::tvec3( - imulExtended(x[0], y[0], msb, lsb), - imulExtended(x[1], y[1], msb, lsb), - imulExtended(x[2], y[2], msb, lsb)); + imulExtended(x[0], y[0], msb[0], lsb[0]), + imulExtended(x[1], y[1], msb[1], lsb[1]); + imulExtended(x[2], y[2], msb[2], lsb[2]); } - template - GLM_FUNC_QUALIFIER detail::tvec4 imulExtended + template <> + GLM_FUNC_QUALIFIER void imulExtended ( - detail::tvec4 const & x, - detail::tvec4 const & y, - detail::tvec4 & msb, - detail::tvec4 & lsb + ivec4 const & x, + ivec4 const & y, + ivec4 & msb, + ivec4 & lsb ) { - return detail::tvec4( - imulExtended(x[0], y[0], msb, lsb), - imulExtended(x[1], y[1], msb, lsb), - imulExtended(x[2], y[2], msb, lsb), - imulExtended(x[3], y[3], msb, lsb)); + imulExtended(x[0], y[0], msb[0], lsb[0]), + imulExtended(x[1], y[1], msb[1], lsb[1]); + imulExtended(x[2], y[2], msb[2], lsb[2]); + imulExtended(x[3], y[3], msb[3], lsb[3]); } // bitfieldExtract diff --git a/readme.txt b/readme.txt index 7fa5f0c9..0d4d32a2 100644 --- a/readme.txt +++ b/readme.txt @@ -67,6 +67,7 @@ GLM 0.9.5.0: 2013-XX-XX - Increased unit tests completness - Added creating of a quaternion from two vectors - Added C++11 initializer lists +- Fixed umulExtended and imulExtended implementations for vector types (#76) ================================================================================ GLM 0.9.4.6: 2013-09-20