From 087d6292e3807ab5d8853546827c9087cad25041 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 26 Oct 2014 00:22:08 +0200 Subject: [PATCH] Added GTC_bitfield extension, promoted GTX_bit --- glm/gtc/bitfield.hpp | 187 ++++++++++++ glm/gtc/bitfield.inl | 509 +++++++++++++++++++++++++++++++++ glm/gtc/constants.inl | 6 +- glm/gtx/bit.hpp | 133 +-------- glm/gtx/bit.inl | 578 -------------------------------------- readme.txt | 1 + test/gtc/CMakeLists.txt | 1 + test/gtc/gtc_bitfield.cpp | 512 +++++++++++++++++++++++++++++++++ test/gtx/gtx_bit.cpp | 491 +------------------------------- 9 files changed, 1216 insertions(+), 1202 deletions(-) create mode 100644 glm/gtc/bitfield.hpp create mode 100644 glm/gtc/bitfield.inl create mode 100644 test/gtc/gtc_bitfield.cpp diff --git a/glm/gtc/bitfield.hpp b/glm/gtc/bitfield.hpp new file mode 100644 index 00000000..bd98bf51 --- /dev/null +++ b/glm/gtc/bitfield.hpp @@ -0,0 +1,187 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2014 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. +/// +/// 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 gtc_bit +/// @file glm/gtc/bitfield.hpp +/// @date 2014-10-25 / 2014-10-25 +/// @author Christophe Riccio +/// +/// @see core (dependence) +/// @see gtc_bitfield (dependence) +/// +/// @defgroup gtc_bitfield GLM_GTC_bitfield +/// @ingroup gtc +/// +/// @brief Allow to perform bit operations on integer values +/// +/// need to be included to use these functionalities. +/////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +// Dependencies +#include "../detail/setup.hpp" +#include "../detail/precision.hpp" +#include "../detail/type_int.hpp" + +#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) +# pragma message("GLM: GLM_GTC_bitfield extension included") +#endif + +namespace glm +{ + /// @addtogroup gtc_bitfield + /// @{ + + /// Build a mask of 'count' bits + /// @see gtc_bitfield + GLM_FUNC_DECL int mask(int Bits); + + template class vecType> + GLM_FUNC_DECL vecType mask(vecType const & v); + + /// Rotate all bits to the right. + /// @see gtc_bitfield + template + GLM_FUNC_DECL genType bitRotateRight(genType In, int Shift); + + /// Rotate all bits to the left. + /// @see gtc_bitfield + template + GLM_FUNC_DECL genType bitRotateLeft(genType In, int Shift); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int16 bitfieldInterleave(int8 x, int8 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint16 bitfieldInterleave(uint8 x, uint8 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int16 x, int16 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint16 x, uint16 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y); + + /// Interleaves the bits of x and y. + /// The first bit is the first bit of x followed by the first bit of y. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y, int32 z); + + /// Interleaves the bits of x, y and z. + /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w); + + /// Interleaves the bits of x, y, z and w. + /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. + /// The other bits are interleaved following the previous sequence. + /// + /// @see gtc_bitfield + GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w); + + /// @} +} //namespace glm + +#include "bitfield.inl" diff --git a/glm/gtc/bitfield.inl b/glm/gtc/bitfield.inl new file mode 100644 index 00000000..7b0b027d --- /dev/null +++ b/glm/gtc/bitfield.inl @@ -0,0 +1,509 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2014 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. +/// +/// 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 gtc_bitfield +/// @file glm/gtc/bitfield.inl +/// @date 2011-10-14 / 2012-01-25 +/// @author Christophe Riccio +/////////////////////////////////////////////////////////////////////////////////// + +namespace glm{ +namespace detail +{ + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y); + + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z); + + template + GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w); + + template <> + GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y) + { + glm::uint16 REG1(x); + glm::uint16 REG2(y); + + REG1 = ((REG1 << 4) | REG1) & glm::uint16(0x0F0F); + REG2 = ((REG2 << 4) | REG2) & glm::uint16(0x0F0F); + + REG1 = ((REG1 << 2) | REG1) & glm::uint16(0x3333); + REG2 = ((REG2 << 2) | REG2) & glm::uint16(0x3333); + + REG1 = ((REG1 << 1) | REG1) & glm::uint16(0x5555); + REG2 = ((REG2 << 1) | REG2) & glm::uint16(0x5555); + + return REG1 | (REG2 << 1); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + + REG1 = ((REG1 << 8) | REG1) & glm::uint32(0x00FF00FF); + REG2 = ((REG2 << 8) | REG2) & glm::uint32(0x00FF00FF); + + REG1 = ((REG1 << 4) | REG1) & glm::uint32(0x0F0F0F0F); + REG2 = ((REG2 << 4) | REG2) & glm::uint32(0x0F0F0F0F); + + REG1 = ((REG1 << 2) | REG1) & glm::uint32(0x33333333); + REG2 = ((REG2 << 2) | REG2) & glm::uint32(0x33333333); + + REG1 = ((REG1 << 1) | REG1) & glm::uint32(0x55555555); + REG2 = ((REG2 << 1) | REG2) & glm::uint32(0x55555555); + + return REG1 | (REG2 << 1); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + + REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + + REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + + REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + + REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + + REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + + return REG1 | (REG2 << 1); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + + REG1 = ((REG1 << 16) | REG1) & glm::uint32(0x00FF0000FF0000FF); + REG2 = ((REG2 << 16) | REG2) & glm::uint32(0x00FF0000FF0000FF); + REG3 = ((REG3 << 16) | REG3) & glm::uint32(0x00FF0000FF0000FF); + + REG1 = ((REG1 << 8) | REG1) & glm::uint32(0xF00F00F00F00F00F); + REG2 = ((REG2 << 8) | REG2) & glm::uint32(0xF00F00F00F00F00F); + REG3 = ((REG3 << 8) | REG3) & glm::uint32(0xF00F00F00F00F00F); + + REG1 = ((REG1 << 4) | REG1) & glm::uint32(0x30C30C30C30C30C3); + REG2 = ((REG2 << 4) | REG2) & glm::uint32(0x30C30C30C30C30C3); + REG3 = ((REG3 << 4) | REG3) & glm::uint32(0x30C30C30C30C30C3); + + REG1 = ((REG1 << 2) | REG1) & glm::uint32(0x9249249249249249); + REG2 = ((REG2 << 2) | REG2) & glm::uint32(0x9249249249249249); + REG3 = ((REG3 << 2) | REG3) & glm::uint32(0x9249249249249249); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + + REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF); + REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF); + REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF); + + REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF); + REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF); + REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF); + + REG1 = ((REG1 << 8) | REG1) & glm::uint64(0xF00F00F00F00F00F); + REG2 = ((REG2 << 8) | REG2) & glm::uint64(0xF00F00F00F00F00F); + REG3 = ((REG3 << 8) | REG3) & glm::uint64(0xF00F00F00F00F00F); + + REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x30C30C30C30C30C3); + REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x30C30C30C30C30C3); + REG3 = ((REG3 << 4) | REG3) & glm::uint64(0x30C30C30C30C30C3); + + REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x9249249249249249); + REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x9249249249249249); + REG3 = ((REG3 << 2) | REG3) & glm::uint64(0x9249249249249249); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + + REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF); + REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF); + REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF); + + REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF); + REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF); + REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF); + + REG1 = ((REG1 << 8) | REG1) & glm::uint64(0xF00F00F00F00F00F); + REG2 = ((REG2 << 8) | REG2) & glm::uint64(0xF00F00F00F00F00F); + REG3 = ((REG3 << 8) | REG3) & glm::uint64(0xF00F00F00F00F00F); + + REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x30C30C30C30C30C3); + REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x30C30C30C30C30C3); + REG3 = ((REG3 << 4) | REG3) & glm::uint64(0x30C30C30C30C30C3); + + REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x9249249249249249); + REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x9249249249249249); + REG3 = ((REG3 << 2) | REG3) & glm::uint64(0x9249249249249249); + + return REG1 | (REG2 << 1) | (REG3 << 2); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w) + { + glm::uint32 REG1(x); + glm::uint32 REG2(y); + glm::uint32 REG3(z); + glm::uint32 REG4(w); + + REG1 = ((REG1 << 12) | REG1) & glm::uint32(0x000F000F000F000F); + REG2 = ((REG2 << 12) | REG2) & glm::uint32(0x000F000F000F000F); + REG3 = ((REG3 << 12) | REG3) & glm::uint32(0x000F000F000F000F); + REG4 = ((REG4 << 12) | REG4) & glm::uint32(0x000F000F000F000F); + + REG1 = ((REG1 << 6) | REG1) & glm::uint32(0x0303030303030303); + REG2 = ((REG2 << 6) | REG2) & glm::uint32(0x0303030303030303); + REG3 = ((REG3 << 6) | REG3) & glm::uint32(0x0303030303030303); + REG4 = ((REG4 << 6) | REG4) & glm::uint32(0x0303030303030303); + + REG1 = ((REG1 << 3) | REG1) & glm::uint32(0x1111111111111111); + REG2 = ((REG2 << 3) | REG2) & glm::uint32(0x1111111111111111); + REG3 = ((REG3 << 3) | REG3) & glm::uint32(0x1111111111111111); + REG4 = ((REG4 << 3) | REG4) & glm::uint32(0x1111111111111111); + + return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); + } + + template <> + GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w) + { + glm::uint64 REG1(x); + glm::uint64 REG2(y); + glm::uint64 REG3(z); + glm::uint64 REG4(w); + + REG1 = ((REG1 << 24) | REG1) & glm::uint64(0x000000FF000000FF); + REG2 = ((REG2 << 24) | REG2) & glm::uint64(0x000000FF000000FF); + REG3 = ((REG3 << 24) | REG3) & glm::uint64(0x000000FF000000FF); + REG4 = ((REG4 << 24) | REG4) & glm::uint64(0x000000FF000000FF); + + REG1 = ((REG1 << 12) | REG1) & glm::uint64(0x000F000F000F000F); + REG2 = ((REG2 << 12) | REG2) & glm::uint64(0x000F000F000F000F); + REG3 = ((REG3 << 12) | REG3) & glm::uint64(0x000F000F000F000F); + REG4 = ((REG4 << 12) | REG4) & glm::uint64(0x000F000F000F000F); + + REG1 = ((REG1 << 6) | REG1) & glm::uint64(0x0303030303030303); + REG2 = ((REG2 << 6) | REG2) & glm::uint64(0x0303030303030303); + REG3 = ((REG3 << 6) | REG3) & glm::uint64(0x0303030303030303); + REG4 = ((REG4 << 6) | REG4) & glm::uint64(0x0303030303030303); + + REG1 = ((REG1 << 3) | REG1) & glm::uint64(0x1111111111111111); + REG2 = ((REG2 << 3) | REG2) & glm::uint64(0x1111111111111111); + REG3 = ((REG3 << 3) | REG3) & glm::uint64(0x1111111111111111); + REG4 = ((REG4 << 3) | REG4) & glm::uint64(0x1111111111111111); + + return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); + } +}//namespace detail + + GLM_FUNC_QUALIFIER int mask(int Bits) + { + return Bits >= sizeof(Bits) * 8 ? ~static_cast(0) : (static_cast(1) << Bits) - static_cast(1); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType mask(vecType const & v) + { + return detail::functor1::call(mask, v); + } + + template + GLM_FUNC_QUALIFIER genType bitRotateRight(genType In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateRight' only accept integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In << static_cast(Shift)) | (In >> static_cast(BitSize - Shift)); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType bitRotateRight(vecType const & Value, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateRight' only accept integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In << static_cast(Shift)) | (In >> static_cast(BitSize - Shift)); + } + + template + GLM_FUNC_QUALIFIER genType bitRotateLeft(genType In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateLeft' only accept integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In >> static_cast(Shift)) | (In << static_cast(BitSize - Shift)); + } + + template class vecType> + GLM_FUNC_QUALIFIER vecType bitRotateLeft(vecType const & In, int Shift) + { + GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateLeft' only accept integer values"); + + int const BitSize = static_cast(sizeof(T) * 8); + return (In >> static_cast(Shift)) | (In << static_cast(BitSize - Shift)); + } + + GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y; + + union sign16 + { + int16 i; + uint16 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y) + { + union sign32 + { + int32 i; + uint32 u; + } sign_x, sign_y; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + result.u = bitfieldInterleave(sign_x.u, sign_y.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y) + { + return detail::bitfieldInterleave(x, y); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y, sign_z; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y, sign_z; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z) + { + union sign16 + { + int32 i; + uint32 u; + } sign_x, sign_y, sign_z; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z) + { + return detail::bitfieldInterleave(x, y, z); + } + + GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w) + { + union sign8 + { + int8 i; + uint8 u; + } sign_x, sign_y, sign_z, sign_w; + + union sign32 + { + int32 i; + uint32 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + sign_w.i = w; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w) + { + return detail::bitfieldInterleave(x, y, z, w); + } + + GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w) + { + union sign16 + { + int16 i; + uint16 u; + } sign_x, sign_y, sign_z, sign_w; + + union sign64 + { + int64 i; + uint64 u; + } result; + + sign_x.i = x; + sign_y.i = y; + sign_z.i = z; + sign_w.i = w; + result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); + + return result.i; + } + + GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w) + { + return detail::bitfieldInterleave(x, y, z, w); + } +}//namespace glm diff --git a/glm/gtc/constants.inl b/glm/gtc/constants.inl index a9ea0095..d74c53d7 100644 --- a/glm/gtc/constants.inl +++ b/glm/gtc/constants.inl @@ -20,9 +20,9 @@ /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN /// THE SOFTWARE. /// -/// @ref gtx_constants -/// @file glm/gtx/constants.inl -/// @date 2011-10-14 / 2012-01-25 +/// @ref gtc_constants +/// @file glm/gtc/constants.inl +/// @date 2011-10-14 / 2014-10-25 /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// diff --git a/glm/gtx/bit.hpp b/glm/gtx/bit.hpp index b85e9388..eb044181 100644 --- a/glm/gtx/bit.hpp +++ b/glm/gtx/bit.hpp @@ -42,6 +42,7 @@ #include "../detail/type_int.hpp" #include "../detail/setup.hpp" #include "../detail/precision.hpp" +#include "../gtc/bitfield.hpp" #include #if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED)) @@ -50,16 +51,6 @@ namespace glm { - /// @addtogroup gtx_bit - /// @{ - - /// Build a mask of 'count' bits - /// @see gtx_bit - GLM_FUNC_DECL int mask(int Bits); - - template class vecType> - GLM_FUNC_DECL vecType mask(vecType const & v); - //! Find the highest bit set to 1 in a integer variable and return its value. /// @see gtx_bit template @@ -90,16 +81,6 @@ namespace glm template GLM_DEPRECATED GLM_FUNC_DECL genType bitRevert(genType const & value); - //! Rotate all bits to the right. - /// @see gtx_bit - template - GLM_FUNC_DECL genType bitRotateRight(genType const & In, std::size_t Shift); - - //! Rotate all bits to the left. - /// @see gtx_bit - template - GLM_FUNC_DECL genType bitRotateLeft(genType const & In, std::size_t Shift); - //! Set to 1 a range of bits. /// @see gtx_bit template @@ -116,118 +97,6 @@ namespace glm int const & FromBit, int const & ToBit); - /// Interleaves the bits of x and y. - /// The first bit is the first bit of x followed by the first bit of y. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int16 bitfieldInterleave(int8 x, int8 y); - - /// Interleaves the bits of x and y. - /// The first bit is the first bit of x followed by the first bit of y. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint16 bitfieldInterleave(uint8 x, uint8 y); - - /// Interleaves the bits of x and y. - /// The first bit is the first bit of x followed by the first bit of y. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int32 bitfieldInterleave(int16 x, int16 y); - - /// Interleaves the bits of x and y. - /// The first bit is the first bit of x followed by the first bit of y. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint32 bitfieldInterleave(uint16 x, uint16 y); - - /// Interleaves the bits of x and y. - /// The first bit is the first bit of x followed by the first bit of y. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y); - - /// Interleaves the bits of x and y. - /// The first bit is the first bit of x followed by the first bit of y. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y); - - /// Interleaves the bits of x, y and z. - /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z); - - /// Interleaves the bits of x, y and z. - /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z); - - /// Interleaves the bits of x, y and z. - /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z); - - /// Interleaves the bits of x, y and z. - /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z); - - /// Interleaves the bits of x, y and z. - /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int64 bitfieldInterleave(int32 x, int32 y, int32 z); - - /// Interleaves the bits of x, y and z. - /// The first bit is the first bit of x followed by the first bit of y and the first bit of z. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z); - - /// Interleaves the bits of x, y, z and w. - /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w); - - /// Interleaves the bits of x, y, z and w. - /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w); - - /// Interleaves the bits of x, y, z and w. - /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w); - - /// Interleaves the bits of x, y, z and w. - /// The first bit is the first bit of x followed by the first bit of y, the first bit of z and finally the first bit of w. - /// The other bits are interleaved following the previous sequence. - /// - /// @see gtx_bit - GLM_FUNC_DECL uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w); - /// @} } //namespace glm diff --git a/glm/gtx/bit.inl b/glm/gtx/bit.inl index c773c82f..21d84d47 100644 --- a/glm/gtx/bit.inl +++ b/glm/gtx/bit.inl @@ -12,17 +12,6 @@ namespace glm { - GLM_FUNC_QUALIFIER int mask(int Bits) - { - return Bits >= sizeof(Bits) * 8 ? ~static_cast(0) : (static_cast(1) << Bits) - static_cast(1); - } - - template class vecType> - GLM_FUNC_QUALIFIER vecType mask(vecType const & v) - { - return detail::functor1::call(mask, v); - } - // highestBitValue template GLM_FUNC_QUALIFIER genType highestBitValue @@ -179,102 +168,6 @@ namespace glm VECTORIZE_VEC(bitRevert) - template - GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateRight' only accept integer values"); - - std::size_t BitSize = sizeof(genType) * 8; - return (In << Shift) | (In >> (BitSize - Shift)); - } - - template - GLM_FUNC_QUALIFIER tvec2 bitRotateRight - ( - tvec2 const & Value, - std::size_t Shift - ) - { - return tvec2( - bitRotateRight(Value[0], Shift), - bitRotateRight(Value[1], Shift)); - } - - template - GLM_FUNC_QUALIFIER tvec3 bitRotateRight - ( - tvec3 const & Value, - std::size_t Shift - ) - { - return tvec3( - bitRotateRight(Value[0], Shift), - bitRotateRight(Value[1], Shift), - bitRotateRight(Value[2], Shift)); - } - - template - GLM_FUNC_QUALIFIER tvec4 bitRotateRight - ( - tvec4 const & Value, - std::size_t Shift - ) - { - return tvec4( - bitRotateRight(Value[0], Shift), - bitRotateRight(Value[1], Shift), - bitRotateRight(Value[2], Shift), - bitRotateRight(Value[3], Shift)); - } - - template - GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift) - { - GLM_STATIC_ASSERT(std::numeric_limits::is_integer, "'bitRotateLeft' only accept integer values"); - - std::size_t BitSize = sizeof(genType) * 8; - return (In >> Shift) | (In << (BitSize - Shift)); - } - - template - GLM_FUNC_QUALIFIER tvec2 bitRotateLeft - ( - tvec2 const & Value, - std::size_t Shift - ) - { - return tvec2( - bitRotateLeft(Value[0], Shift), - bitRotateLeft(Value[1], Shift)); - } - - template - GLM_FUNC_QUALIFIER tvec3 bitRotateLeft - ( - tvec3 const & Value, - std::size_t Shift - ) - { - return tvec3( - bitRotateLeft(Value[0], Shift), - bitRotateLeft(Value[1], Shift), - bitRotateLeft(Value[2], Shift)); - } - - template - GLM_FUNC_QUALIFIER tvec4 bitRotateLeft - ( - tvec4 const & Value, - std::size_t Shift - ) - { - return tvec4( - bitRotateLeft(Value[0], Shift), - bitRotateLeft(Value[1], Shift), - bitRotateLeft(Value[2], Shift), - bitRotateLeft(Value[3], Shift)); - } - template GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne ( @@ -308,475 +201,4 @@ namespace glm Result &= ~(1 << i); return Result; } - - namespace detail - { - template - GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y); - - template - GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z); - - template - GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w); - -/* - template - inline RET bitfieldInterleave(PARAM x, PARAM y) - { - RET Result = 0; - for (int i = 0; i < sizeof(PARAM) * 8; i++) - Result |= (x & 1U << i) << i | (y & 1U << i) << (i + 1); - return Result; - } - - template - inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z) - { - RET Result = 0; - for (RET i = 0; i < sizeof(PARAM) * 8; i++) - { - Result |= ((RET(x) & (RET(1) << i)) << ((i << 1) + 0)); - Result |= ((RET(y) & (RET(1) << i)) << ((i << 1) + 1)); - Result |= ((RET(z) & (RET(1) << i)) << ((i << 1) + 2)); - } - return Result; - } - - template - inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w) - { - RET Result = 0; - for (int i = 0; i < sizeof(PARAM) * 8; i++) - { - Result |= ((((RET(x) >> i) & RET(1))) << RET((i << 2) + 0)); - Result |= ((((RET(y) >> i) & RET(1))) << RET((i << 2) + 1)); - Result |= ((((RET(z) >> i) & RET(1))) << RET((i << 2) + 2)); - Result |= ((((RET(w) >> i) & RET(1))) << RET((i << 2) + 3)); - } - return Result; - } -*/ - template <> - GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y) - { - glm::uint16 REG1(x); - glm::uint16 REG2(y); - - REG1 = ((REG1 << 4) | REG1) & glm::uint16(0x0F0F); - REG2 = ((REG2 << 4) | REG2) & glm::uint16(0x0F0F); - - REG1 = ((REG1 << 2) | REG1) & glm::uint16(0x3333); - REG2 = ((REG2 << 2) | REG2) & glm::uint16(0x3333); - - REG1 = ((REG1 << 1) | REG1) & glm::uint16(0x5555); - REG2 = ((REG2 << 1) | REG2) & glm::uint16(0x5555); - - return REG1 | (REG2 << 1); - } - - template <> - GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y) - { - glm::uint32 REG1(x); - glm::uint32 REG2(y); - - REG1 = ((REG1 << 8) | REG1) & glm::uint32(0x00FF00FF); - REG2 = ((REG2 << 8) | REG2) & glm::uint32(0x00FF00FF); - - REG1 = ((REG1 << 4) | REG1) & glm::uint32(0x0F0F0F0F); - REG2 = ((REG2 << 4) | REG2) & glm::uint32(0x0F0F0F0F); - - REG1 = ((REG1 << 2) | REG1) & glm::uint32(0x33333333); - REG2 = ((REG2 << 2) | REG2) & glm::uint32(0x33333333); - - REG1 = ((REG1 << 1) | REG1) & glm::uint32(0x55555555); - REG2 = ((REG2 << 1) | REG2) & glm::uint32(0x55555555); - - return REG1 | (REG2 << 1); - } - - template <> - GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y) - { - glm::uint64 REG1(x); - glm::uint64 REG2(y); - - REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); - REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); - - REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); - REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); - - REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); - REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); - - REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); - REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); - - REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); - REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); - - return REG1 | (REG2 << 1); - } - - template <> - GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z) - { - glm::uint32 REG1(x); - glm::uint32 REG2(y); - glm::uint32 REG3(z); - - REG1 = ((REG1 << 16) | REG1) & glm::uint32(0x00FF0000FF0000FF); - REG2 = ((REG2 << 16) | REG2) & glm::uint32(0x00FF0000FF0000FF); - REG3 = ((REG3 << 16) | REG3) & glm::uint32(0x00FF0000FF0000FF); - - REG1 = ((REG1 << 8) | REG1) & glm::uint32(0xF00F00F00F00F00F); - REG2 = ((REG2 << 8) | REG2) & glm::uint32(0xF00F00F00F00F00F); - REG3 = ((REG3 << 8) | REG3) & glm::uint32(0xF00F00F00F00F00F); - - REG1 = ((REG1 << 4) | REG1) & glm::uint32(0x30C30C30C30C30C3); - REG2 = ((REG2 << 4) | REG2) & glm::uint32(0x30C30C30C30C30C3); - REG3 = ((REG3 << 4) | REG3) & glm::uint32(0x30C30C30C30C30C3); - - REG1 = ((REG1 << 2) | REG1) & glm::uint32(0x9249249249249249); - REG2 = ((REG2 << 2) | REG2) & glm::uint32(0x9249249249249249); - REG3 = ((REG3 << 2) | REG3) & glm::uint32(0x9249249249249249); - - return REG1 | (REG2 << 1) | (REG3 << 2); - } - - template <> - GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z) - { - glm::uint64 REG1(x); - glm::uint64 REG2(y); - glm::uint64 REG3(z); - - REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF); - REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF); - REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF); - - REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF); - REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF); - REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF); - - REG1 = ((REG1 << 8) | REG1) & glm::uint64(0xF00F00F00F00F00F); - REG2 = ((REG2 << 8) | REG2) & glm::uint64(0xF00F00F00F00F00F); - REG3 = ((REG3 << 8) | REG3) & glm::uint64(0xF00F00F00F00F00F); - - REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x30C30C30C30C30C3); - REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x30C30C30C30C30C3); - REG3 = ((REG3 << 4) | REG3) & glm::uint64(0x30C30C30C30C30C3); - - REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x9249249249249249); - REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x9249249249249249); - REG3 = ((REG3 << 2) | REG3) & glm::uint64(0x9249249249249249); - - return REG1 | (REG2 << 1) | (REG3 << 2); - } - - template <> - GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z) - { - glm::uint64 REG1(x); - glm::uint64 REG2(y); - glm::uint64 REG3(z); - - REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF); - REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF); - REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF); - - REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF); - REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF); - REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF); - - REG1 = ((REG1 << 8) | REG1) & glm::uint64(0xF00F00F00F00F00F); - REG2 = ((REG2 << 8) | REG2) & glm::uint64(0xF00F00F00F00F00F); - REG3 = ((REG3 << 8) | REG3) & glm::uint64(0xF00F00F00F00F00F); - - REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x30C30C30C30C30C3); - REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x30C30C30C30C30C3); - REG3 = ((REG3 << 4) | REG3) & glm::uint64(0x30C30C30C30C30C3); - - REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x9249249249249249); - REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x9249249249249249); - REG3 = ((REG3 << 2) | REG3) & glm::uint64(0x9249249249249249); - - return REG1 | (REG2 << 1) | (REG3 << 2); - } - - template <> - GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w) - { - glm::uint32 REG1(x); - glm::uint32 REG2(y); - glm::uint32 REG3(z); - glm::uint32 REG4(w); - - REG1 = ((REG1 << 12) | REG1) & glm::uint32(0x000F000F000F000F); - REG2 = ((REG2 << 12) | REG2) & glm::uint32(0x000F000F000F000F); - REG3 = ((REG3 << 12) | REG3) & glm::uint32(0x000F000F000F000F); - REG4 = ((REG4 << 12) | REG4) & glm::uint32(0x000F000F000F000F); - - REG1 = ((REG1 << 6) | REG1) & glm::uint32(0x0303030303030303); - REG2 = ((REG2 << 6) | REG2) & glm::uint32(0x0303030303030303); - REG3 = ((REG3 << 6) | REG3) & glm::uint32(0x0303030303030303); - REG4 = ((REG4 << 6) | REG4) & glm::uint32(0x0303030303030303); - - REG1 = ((REG1 << 3) | REG1) & glm::uint32(0x1111111111111111); - REG2 = ((REG2 << 3) | REG2) & glm::uint32(0x1111111111111111); - REG3 = ((REG3 << 3) | REG3) & glm::uint32(0x1111111111111111); - REG4 = ((REG4 << 3) | REG4) & glm::uint32(0x1111111111111111); - - return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); - } - - template <> - GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w) - { - glm::uint64 REG1(x); - glm::uint64 REG2(y); - glm::uint64 REG3(z); - glm::uint64 REG4(w); - - REG1 = ((REG1 << 24) | REG1) & glm::uint64(0x000000FF000000FF); - REG2 = ((REG2 << 24) | REG2) & glm::uint64(0x000000FF000000FF); - REG3 = ((REG3 << 24) | REG3) & glm::uint64(0x000000FF000000FF); - REG4 = ((REG4 << 24) | REG4) & glm::uint64(0x000000FF000000FF); - - REG1 = ((REG1 << 12) | REG1) & glm::uint64(0x000F000F000F000F); - REG2 = ((REG2 << 12) | REG2) & glm::uint64(0x000F000F000F000F); - REG3 = ((REG3 << 12) | REG3) & glm::uint64(0x000F000F000F000F); - REG4 = ((REG4 << 12) | REG4) & glm::uint64(0x000F000F000F000F); - - REG1 = ((REG1 << 6) | REG1) & glm::uint64(0x0303030303030303); - REG2 = ((REG2 << 6) | REG2) & glm::uint64(0x0303030303030303); - REG3 = ((REG3 << 6) | REG3) & glm::uint64(0x0303030303030303); - REG4 = ((REG4 << 6) | REG4) & glm::uint64(0x0303030303030303); - - REG1 = ((REG1 << 3) | REG1) & glm::uint64(0x1111111111111111); - REG2 = ((REG2 << 3) | REG2) & glm::uint64(0x1111111111111111); - REG3 = ((REG3 << 3) | REG3) & glm::uint64(0x1111111111111111); - REG4 = ((REG4 << 3) | REG4) & glm::uint64(0x1111111111111111); - - return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); - } - }//namespace detail - - GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y) - { - union sign8 - { - int8 i; - uint8 u; - } sign_x, sign_y; - - union sign16 - { - int16 i; - uint16 u; - } result; - - sign_x.i = x; - sign_y.i = y; - result.u = bitfieldInterleave(sign_x.u, sign_y.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y) - { - return detail::bitfieldInterleave(x, y); - } - - GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y) - { - union sign16 - { - int16 i; - uint16 u; - } sign_x, sign_y; - - union sign32 - { - int32 i; - uint32 u; - } result; - - sign_x.i = x; - sign_y.i = y; - result.u = bitfieldInterleave(sign_x.u, sign_y.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y) - { - return detail::bitfieldInterleave(x, y); - } - - GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y) - { - union sign32 - { - int32 i; - uint32 u; - } sign_x, sign_y; - - union sign64 - { - int64 i; - uint64 u; - } result; - - sign_x.i = x; - sign_y.i = y; - result.u = bitfieldInterleave(sign_x.u, sign_y.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y) - { - return detail::bitfieldInterleave(x, y); - } - - GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z) - { - union sign8 - { - int8 i; - uint8 u; - } sign_x, sign_y, sign_z; - - union sign32 - { - int32 i; - uint32 u; - } result; - - sign_x.i = x; - sign_y.i = y; - sign_z.i = z; - result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z) - { - return detail::bitfieldInterleave(x, y, z); - } - - GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z) - { - union sign16 - { - int16 i; - uint16 u; - } sign_x, sign_y, sign_z; - - union sign64 - { - int64 i; - uint64 u; - } result; - - sign_x.i = x; - sign_y.i = y; - sign_z.i = z; - result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z) - { - return detail::bitfieldInterleave(x, y, z); - } - - GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z) - { - union sign16 - { - int32 i; - uint32 u; - } sign_x, sign_y, sign_z; - - union sign64 - { - int64 i; - uint64 u; - } result; - - sign_x.i = x; - sign_y.i = y; - sign_z.i = z; - result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z) - { - return detail::bitfieldInterleave(x, y, z); - } - - GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w) - { - union sign8 - { - int8 i; - uint8 u; - } sign_x, sign_y, sign_z, sign_w; - - union sign32 - { - int32 i; - uint32 u; - } result; - - sign_x.i = x; - sign_y.i = y; - sign_z.i = z; - sign_w.i = w; - result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w) - { - return detail::bitfieldInterleave(x, y, z, w); - } - - GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w) - { - union sign16 - { - int16 i; - uint16 u; - } sign_x, sign_y, sign_z, sign_w; - - union sign64 - { - int64 i; - uint64 u; - } result; - - sign_x.i = x; - sign_y.i = y; - sign_z.i = z; - sign_w.i = w; - result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); - - return result.i; - } - - GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w) - { - return detail::bitfieldInterleave(x, y, z, w); - } - }//namespace glm diff --git a/readme.txt b/readme.txt index 43392cb5..73827a83 100644 --- a/readme.txt +++ b/readme.txt @@ -77,6 +77,7 @@ GLM 0.9.6.0: 2014-XX-XX - Added 'uninitialize' to explicitly not initialize a GLM type - Added not function (from GLSL specification) on VC12 - Optimized bitfield operations +- Added GTC_bitfield extension, promoted GTX_bit ================================================================================ GLM 0.9.5.4: 2014-06-21 diff --git a/test/gtc/CMakeLists.txt b/test/gtc/CMakeLists.txt index b3d61b0d..6b590df0 100644 --- a/test/gtc/CMakeLists.txt +++ b/test/gtc/CMakeLists.txt @@ -1,3 +1,4 @@ +glmCreateTestGTC(gtc_bitfield) glmCreateTestGTC(gtc_constants) glmCreateTestGTC(gtc_epsilon) glmCreateTestGTC(gtc_matrix_access) diff --git a/test/gtc/gtc_bitfield.cpp b/test/gtc/gtc_bitfield.cpp new file mode 100644 index 00000000..aa9c54c1 --- /dev/null +++ b/test/gtc/gtc_bitfield.cpp @@ -0,0 +1,512 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Created : 2014-10-25 +// Updated : 2014-10-25 +// Licence : This source is under MIT licence +// File : test/gtc/bitfield.cpp +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +//#include +#include +#include +#include + +namespace mask +{ + inline int mask_mix(int Bits) + { + return Bits >= 32 ? 0xffffffff : (static_cast(1) << Bits) - static_cast(1); + } + + inline int mask_loop(int Bits) + { + int Mask = 0; + for(int Bit = 0; Bit < Bits; ++Bit) + Mask |= (static_cast(1) << Bit); + return Mask; + } + + int perf() + { + int const Count = 100000000; + + std::clock_t Timestamp1 = std::clock(); + + { + std::vector Mask; + Mask.resize(Count); + for(int i = 0; i < Count; ++i) + Mask[i] = mask_mix(i % 32); + } + + std::clock_t Timestamp2 = std::clock(); + + { + std::vector Mask; + Mask.resize(Count); + for(int i = 0; i < Count; ++i) + Mask[i] = mask_loop(i % 32); + } + + std::clock_t Timestamp3 = std::clock(); + + { + std::vector Mask; + Mask.resize(Count); + for(int i = 0; i < Count; ++i) + Mask[i] = glm::mask(i % 32); + } + + std::clock_t Timestamp4 = std::clock(); + + std::clock_t TimeMix = Timestamp2 - Timestamp1; + std::clock_t TimeLoop = Timestamp3 - Timestamp2; + std::clock_t TimeDefault = Timestamp4 - Timestamp3; + + printf("mask[mix]: %d\n", TimeMix); + printf("mask[loop]: %d\n", TimeLoop); + printf("mask[default]: %d\n", TimeDefault); + + return TimeDefault < TimeLoop ? 0 : 1; + } +}//namespace mask + + +namespace bitfieldInterleave3 +{ + template + inline RET refBitfieldInterleave(PARAM x, PARAM y, PARAM z) + { + RET Result = 0; + for(RET i = 0; i < sizeof(PARAM) * 8; ++i) + { + Result |= ((RET(x) & (RET(1U) << i)) << ((i << 1) + 0)); + Result |= ((RET(y) & (RET(1U) << i)) << ((i << 1) + 1)); + Result |= ((RET(z) & (RET(1U) << i)) << ((i << 1) + 2)); + } + return Result; + } + + int test() + { + int Error(0); + + glm::uint16 x_max = 1 << 11; + glm::uint16 y_max = 1 << 11; + glm::uint16 z_max = 1 << 11; + + for(glm::uint16 z = 0; z < z_max; z += 27) + for(glm::uint16 y = 0; y < y_max; y += 27) + for(glm::uint16 x = 0; x < x_max; x += 27) + { + glm::uint64 ResultA = refBitfieldInterleave(x, y, z); + glm::uint64 ResultB = glm::bitfieldInterleave(x, y, z); + Error += ResultA == ResultB ? 0 : 1; + } + + return Error; + } +} + +namespace bitfieldInterleave4 +{ + template + inline RET loopBitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w) + { + RET const v[4] = {x, y, z, w}; + RET Result = 0; + for(RET i = 0; i < sizeof(PARAM) * 8; i++) + { + Result |= ((((v[0] >> i) & 1U)) << ((i << 2) + 0)); + Result |= ((((v[1] >> i) & 1U)) << ((i << 2) + 1)); + Result |= ((((v[2] >> i) & 1U)) << ((i << 2) + 2)); + Result |= ((((v[3] >> i) & 1U)) << ((i << 2) + 3)); + } + return Result; + } + + int test() + { + int Error(0); + + glm::uint16 x_max = 1 << 11; + glm::uint16 y_max = 1 << 11; + glm::uint16 z_max = 1 << 11; + glm::uint16 w_max = 1 << 11; + + for(glm::uint16 w = 0; w < w_max; w += 27) + for(glm::uint16 z = 0; z < z_max; z += 27) + for(glm::uint16 y = 0; y < y_max; y += 27) + for(glm::uint16 x = 0; x < x_max; x += 27) + { + glm::uint64 ResultA = loopBitfieldInterleave(x, y, z, w); + glm::uint64 ResultB = glm::bitfieldInterleave(x, y, z, w); + Error += ResultA == ResultB ? 0 : 1; + } + + return Error; + } +} + +namespace bitfieldInterleave +{ + inline glm::uint64 fastBitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + glm::uint64 REG1; + glm::uint64 REG2; + + REG1 = x; + REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + + REG2 = y; + REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + + return REG1 | (REG2 << 1); + } + + inline glm::uint64 interleaveBitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + glm::uint64 REG1; + glm::uint64 REG2; + + REG1 = x; + REG2 = y; + + REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + + REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + + REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + + REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + + REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + + return REG1 | (REG2 << 1); + } + + inline glm::uint64 loopBitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + static glm::uint64 const Mask[5] = + { + 0x5555555555555555, + 0x3333333333333333, + 0x0F0F0F0F0F0F0F0F, + 0x00FF00FF00FF00FF, + 0x0000FFFF0000FFFF + }; + + glm::uint64 REG1 = x; + glm::uint64 REG2 = y; + for(int i = 4; i >= 0; --i) + { + REG1 = ((REG1 << (1 << i)) | REG1) & Mask[i]; + REG2 = ((REG2 << (1 << i)) | REG2) & Mask[i]; + } + + return REG1 | (REG2 << 1); + } + +#if(GLM_ARCH != GLM_ARCH_PURE) + inline glm::uint64 sseBitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + GLM_ALIGN(16) glm::uint32 const Array[4] = {x, 0, y, 0}; + + __m128i const Mask4 = _mm_set1_epi32(0x0000FFFF); + __m128i const Mask3 = _mm_set1_epi32(0x00FF00FF); + __m128i const Mask2 = _mm_set1_epi32(0x0F0F0F0F); + __m128i const Mask1 = _mm_set1_epi32(0x33333333); + __m128i const Mask0 = _mm_set1_epi32(0x55555555); + + __m128i Reg1; + __m128i Reg2; + + // REG1 = x; + // REG2 = y; + Reg1 = _mm_load_si128((__m128i*)Array); + + //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + Reg2 = _mm_slli_si128(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask4); + + //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + Reg2 = _mm_slli_si128(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask3); + + //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + Reg2 = _mm_slli_epi32(Reg1, 4); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask2); + + //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + Reg2 = _mm_slli_epi32(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask1); + + //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask0); + + //return REG1 | (REG2 << 1); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg2 = _mm_srli_si128(Reg2, 8); + Reg1 = _mm_or_si128(Reg1, Reg2); + + GLM_ALIGN(16) glm::uint64 Result[2]; + _mm_store_si128((__m128i*)Result, Reg1); + + return Result[0]; + } + + inline glm::uint64 sseUnalignedBitfieldInterleave(glm::uint32 x, glm::uint32 y) + { + glm::uint32 const Array[4] = {x, 0, y, 0}; + + __m128i const Mask4 = _mm_set1_epi32(0x0000FFFF); + __m128i const Mask3 = _mm_set1_epi32(0x00FF00FF); + __m128i const Mask2 = _mm_set1_epi32(0x0F0F0F0F); + __m128i const Mask1 = _mm_set1_epi32(0x33333333); + __m128i const Mask0 = _mm_set1_epi32(0x55555555); + + __m128i Reg1; + __m128i Reg2; + + // REG1 = x; + // REG2 = y; + Reg1 = _mm_loadu_si128((__m128i*)Array); + + //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); + //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); + Reg2 = _mm_slli_si128(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask4); + + //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); + //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); + Reg2 = _mm_slli_si128(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask3); + + //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); + //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); + Reg2 = _mm_slli_epi32(Reg1, 4); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask2); + + //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); + //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); + Reg2 = _mm_slli_epi32(Reg1, 2); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask1); + + //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); + //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg1 = _mm_or_si128(Reg2, Reg1); + Reg1 = _mm_and_si128(Reg1, Mask0); + + //return REG1 | (REG2 << 1); + Reg2 = _mm_slli_epi32(Reg1, 1); + Reg2 = _mm_srli_si128(Reg2, 8); + Reg1 = _mm_or_si128(Reg1, Reg2); + + glm::uint64 Result[2]; + _mm_storeu_si128((__m128i*)Result, Reg1); + + return Result[0]; + } +#endif//(GLM_ARCH != GLM_ARCH_PURE) + + int test() + { + glm::uint32 x_max = 1 << 11; + glm::uint32 y_max = 1 << 10; + + // ALU + std::vector Data(x_max * y_max); + std::vector Param(x_max * y_max); + for(glm::uint32 i = 0; i < Param.size(); ++i) + Param[i] = glm::u32vec2(i % x_max, i / y_max); + + { + for(glm::uint32 y = 0; y < (1 << 10); ++y) + for(glm::uint32 x = 0; x < (1 << 10); ++x) + { + glm::uint64 A = glm::bitfieldInterleave(x, y); + glm::uint64 B = fastBitfieldInterleave(x, y); + glm::uint64 C = loopBitfieldInterleave(x, y); + glm::uint64 D = interleaveBitfieldInterleave(x, y); + + assert(A == B); + assert(A == C); + assert(A == D); + +# if(GLM_ARCH != GLM_ARCH_PURE) + glm::uint64 E = sseBitfieldInterleave(x, y); + glm::uint64 F = sseUnalignedBitfieldInterleave(x, y); + assert(A == E); + assert(A == F); + + __m128i G = glm::detail::_mm_bit_interleave_si128(_mm_set_epi32(0, y, 0, x)); + glm::uint64 Result[2]; + _mm_storeu_si128((__m128i*)Result, G); + assert(A == Result[0]); +# endif//(GLM_ARCH != GLM_ARCH_PURE) + } + } + + { + for(glm::uint8 y = 0; y < 127; ++y) + for(glm::uint8 x = 0; x < 127; ++x) + { + glm::uint64 A(glm::bitfieldInterleave(glm::uint8(x), glm::uint8(y))); + glm::uint64 B(glm::bitfieldInterleave(glm::uint16(x), glm::uint16(y))); + glm::uint64 C(glm::bitfieldInterleave(glm::uint32(x), glm::uint32(y))); + + glm::int64 D(glm::bitfieldInterleave(glm::int8(x), glm::int8(y))); + glm::int64 E(glm::bitfieldInterleave(glm::int16(x), glm::int16(y))); + glm::int64 F(glm::bitfieldInterleave(glm::int32(x), glm::int32(y))); + + assert(D == E); + assert(D == F); + } + } + + { + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < Data.size(); ++i) + Data[i] = glm::bitfieldInterleave(Param[i].x, Param[i].y); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("glm::bitfieldInterleave Time %d clocks\n", Time); + } + + { + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < Data.size(); ++i) + Data[i] = fastBitfieldInterleave(Param[i].x, Param[i].y); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("fastBitfieldInterleave Time %d clocks\n", Time); + } + + { + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < Data.size(); ++i) + Data[i] = loopBitfieldInterleave(Param[i].x, Param[i].y); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("loopBitfieldInterleave Time %d clocks\n", Time); + } + + { + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < Data.size(); ++i) + Data[i] = interleaveBitfieldInterleave(Param[i].x, Param[i].y); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("interleaveBitfieldInterleave Time %d clocks\n", Time); + } + +# if(GLM_ARCH != GLM_ARCH_PURE) + { + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < Data.size(); ++i) + Data[i] = sseBitfieldInterleave(Param[i].x, Param[i].y); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("sseBitfieldInterleave Time %d clocks\n", Time); + } + + { + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < Data.size(); ++i) + Data[i] = sseUnalignedBitfieldInterleave(Param[i].x, Param[i].y); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("sseUnalignedBitfieldInterleave Time %d clocks\n", Time); + } +# endif//(GLM_ARCH != GLM_ARCH_PURE) + + { + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < Data.size(); ++i) + Data[i] = glm::bitfieldInterleave(Param[i].x, Param[i].y, Param[i].x); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("glm::detail::bitfieldInterleave Time %d clocks\n", Time); + } + +# if(GLM_ARCH != GLM_ARCH_PURE) + { + // SIMD + std::vector<__m128i> SimdData(x_max * y_max); + std::vector<__m128i> SimdParam(x_max * y_max); + for(int i = 0; i < SimdParam.size(); ++i) + SimdParam[i] = _mm_set_epi32(i % x_max, 0, i / y_max, 0); + + std::clock_t LastTime = std::clock(); + + for(std::size_t i = 0; i < SimdData.size(); ++i) + SimdData[i] = glm::detail::_mm_bit_interleave_si128(SimdParam[i]); + + std::clock_t Time = std::clock() - LastTime; + + std::printf("_mm_bit_interleave_si128 Time %d clocks\n", Time); + } +# endif//(GLM_ARCH != GLM_ARCH_PURE) + + return 0; + } +} + +int main() +{ + int Error(0); + + Error += ::mask::perf(); + Error += ::bitfieldInterleave3::test(); + Error += ::bitfieldInterleave4::test(); + Error += ::bitfieldInterleave::test(); + //Error += ::bitRevert::test(); + + return Error; +} diff --git a/test/gtx/gtx_bit.cpp b/test/gtx/gtx_bit.cpp index 94cea9c6..2dc66375 100644 --- a/test/gtx/gtx_bit.cpp +++ b/test/gtx/gtx_bit.cpp @@ -14,9 +14,9 @@ # include #endif -#include #include #include +#include enum result { @@ -70,7 +70,7 @@ namespace bitRevert else if(Data64[i].Result == FAIL && !Compare) continue; - std::cout << "glm::extractfield test fail on test " << i << std::endl; + printf("glm::extractfield test fail on test %d\n", i); return 1; } @@ -78,497 +78,10 @@ namespace bitRevert } }//bitRevert -namespace bitfieldInterleave -{ - inline glm::uint64 fastBitfieldInterleave(glm::uint32 x, glm::uint32 y) - { - glm::uint64 REG1; - glm::uint64 REG2; - - REG1 = x; - REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); - REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); - REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); - REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); - REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); - - REG2 = y; - REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); - REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); - REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); - REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); - REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); - - return REG1 | (REG2 << 1); - } - - inline glm::uint64 interleaveBitfieldInterleave(glm::uint32 x, glm::uint32 y) - { - glm::uint64 REG1; - glm::uint64 REG2; - - REG1 = x; - REG2 = y; - - REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); - REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); - - REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); - REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); - - REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); - REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); - - REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); - REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); - - REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); - REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); - - return REG1 | (REG2 << 1); - } - - inline glm::uint64 loopBitfieldInterleave(glm::uint32 x, glm::uint32 y) - { - static glm::uint64 const Mask[5] = - { - 0x5555555555555555, - 0x3333333333333333, - 0x0F0F0F0F0F0F0F0F, - 0x00FF00FF00FF00FF, - 0x0000FFFF0000FFFF - }; - - glm::uint64 REG1 = x; - glm::uint64 REG2 = y; - for(int i = 4; i >= 0; --i) - { - REG1 = ((REG1 << (1 << i)) | REG1) & Mask[i]; - REG2 = ((REG2 << (1 << i)) | REG2) & Mask[i]; - } - - return REG1 | (REG2 << 1); - } - -#if(GLM_ARCH != GLM_ARCH_PURE) - inline glm::uint64 sseBitfieldInterleave(glm::uint32 x, glm::uint32 y) - { - GLM_ALIGN(16) glm::uint32 const Array[4] = {x, 0, y, 0}; - - __m128i const Mask4 = _mm_set1_epi32(0x0000FFFF); - __m128i const Mask3 = _mm_set1_epi32(0x00FF00FF); - __m128i const Mask2 = _mm_set1_epi32(0x0F0F0F0F); - __m128i const Mask1 = _mm_set1_epi32(0x33333333); - __m128i const Mask0 = _mm_set1_epi32(0x55555555); - - __m128i Reg1; - __m128i Reg2; - - // REG1 = x; - // REG2 = y; - Reg1 = _mm_load_si128((__m128i*)Array); - - //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); - //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); - Reg2 = _mm_slli_si128(Reg1, 2); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask4); - - //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); - //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); - Reg2 = _mm_slli_si128(Reg1, 1); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask3); - - //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); - //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); - Reg2 = _mm_slli_epi32(Reg1, 4); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask2); - - //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); - //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); - Reg2 = _mm_slli_epi32(Reg1, 2); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask1); - - //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); - //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); - Reg2 = _mm_slli_epi32(Reg1, 1); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask0); - - //return REG1 | (REG2 << 1); - Reg2 = _mm_slli_epi32(Reg1, 1); - Reg2 = _mm_srli_si128(Reg2, 8); - Reg1 = _mm_or_si128(Reg1, Reg2); - - GLM_ALIGN(16) glm::uint64 Result[2]; - _mm_store_si128((__m128i*)Result, Reg1); - - return Result[0]; - } - - inline glm::uint64 sseUnalignedBitfieldInterleave(glm::uint32 x, glm::uint32 y) - { - glm::uint32 const Array[4] = {x, 0, y, 0}; - - __m128i const Mask4 = _mm_set1_epi32(0x0000FFFF); - __m128i const Mask3 = _mm_set1_epi32(0x00FF00FF); - __m128i const Mask2 = _mm_set1_epi32(0x0F0F0F0F); - __m128i const Mask1 = _mm_set1_epi32(0x33333333); - __m128i const Mask0 = _mm_set1_epi32(0x55555555); - - __m128i Reg1; - __m128i Reg2; - - // REG1 = x; - // REG2 = y; - Reg1 = _mm_loadu_si128((__m128i*)Array); - - //REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); - //REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); - Reg2 = _mm_slli_si128(Reg1, 2); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask4); - - //REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); - //REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); - Reg2 = _mm_slli_si128(Reg1, 1); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask3); - - //REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); - //REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); - Reg2 = _mm_slli_epi32(Reg1, 4); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask2); - - //REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); - //REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); - Reg2 = _mm_slli_epi32(Reg1, 2); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask1); - - //REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); - //REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); - Reg2 = _mm_slli_epi32(Reg1, 1); - Reg1 = _mm_or_si128(Reg2, Reg1); - Reg1 = _mm_and_si128(Reg1, Mask0); - - //return REG1 | (REG2 << 1); - Reg2 = _mm_slli_epi32(Reg1, 1); - Reg2 = _mm_srli_si128(Reg2, 8); - Reg1 = _mm_or_si128(Reg1, Reg2); - - glm::uint64 Result[2]; - _mm_storeu_si128((__m128i*)Result, Reg1); - - return Result[0]; - } -#endif//(GLM_ARCH != GLM_ARCH_PURE) - - int test() - { - glm::uint32 x_max = 1 << 11; - glm::uint32 y_max = 1 << 10; - - // ALU - std::vector Data(x_max * y_max); - std::vector Param(x_max * y_max); - for(glm::uint32 i = 0; i < Param.size(); ++i) - Param[i] = glm::u32vec2(i % x_max, i / y_max); - - { - for(glm::uint32 y = 0; y < (1 << 10); ++y) - for(glm::uint32 x = 0; x < (1 << 10); ++x) - { - glm::uint64 A = glm::bitfieldInterleave(x, y); - glm::uint64 B = fastBitfieldInterleave(x, y); - glm::uint64 C = loopBitfieldInterleave(x, y); - glm::uint64 D = interleaveBitfieldInterleave(x, y); - - assert(A == B); - assert(A == C); - assert(A == D); - -# if(GLM_ARCH != GLM_ARCH_PURE) - glm::uint64 E = sseBitfieldInterleave(x, y); - glm::uint64 F = sseUnalignedBitfieldInterleave(x, y); - assert(A == E); - assert(A == F); - - __m128i G = glm::detail::_mm_bit_interleave_si128(_mm_set_epi32(0, y, 0, x)); - glm::uint64 Result[2]; - _mm_storeu_si128((__m128i*)Result, G); - assert(A == Result[0]); -# endif//(GLM_ARCH != GLM_ARCH_PURE) - } - } - - { - for(glm::uint8 y = 0; y < 127; ++y) - for(glm::uint8 x = 0; x < 127; ++x) - { - glm::uint64 A(glm::bitfieldInterleave(glm::uint8(x), glm::uint8(y))); - glm::uint64 B(glm::bitfieldInterleave(glm::uint16(x), glm::uint16(y))); - glm::uint64 C(glm::bitfieldInterleave(glm::uint32(x), glm::uint32(y))); - - glm::int64 D(glm::bitfieldInterleave(glm::int8(x), glm::int8(y))); - glm::int64 E(glm::bitfieldInterleave(glm::int16(x), glm::int16(y))); - glm::int64 F(glm::bitfieldInterleave(glm::int32(x), glm::int32(y))); - - assert(D == E); - assert(D == F); - } - } - - { - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < Data.size(); ++i) - Data[i] = glm::bitfieldInterleave(Param[i].x, Param[i].y); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "glm::bitfieldInterleave Time " << Time << " clocks" << std::endl; - } - - { - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < Data.size(); ++i) - Data[i] = fastBitfieldInterleave(Param[i].x, Param[i].y); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "fastBitfieldInterleave Time " << Time << " clocks" << std::endl; - } - - { - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < Data.size(); ++i) - Data[i] = loopBitfieldInterleave(Param[i].x, Param[i].y); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "loopBitfieldInterleave Time " << Time << " clocks" << std::endl; - } - - { - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < Data.size(); ++i) - Data[i] = interleaveBitfieldInterleave(Param[i].x, Param[i].y); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "interleaveBitfieldInterleave Time " << Time << " clocks" << std::endl; - } - -# if(GLM_ARCH != GLM_ARCH_PURE) - { - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < Data.size(); ++i) - Data[i] = sseBitfieldInterleave(Param[i].x, Param[i].y); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "sseBitfieldInterleave Time " << Time << " clocks" << std::endl; - } - - { - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < Data.size(); ++i) - Data[i] = sseUnalignedBitfieldInterleave(Param[i].x, Param[i].y); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "sseUnalignedBitfieldInterleave Time " << Time << " clocks" << std::endl; - } -# endif//(GLM_ARCH != GLM_ARCH_PURE) - - { - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < Data.size(); ++i) - Data[i] = glm::bitfieldInterleave(Param[i].x, Param[i].y, Param[i].x); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "glm::detail::bitfieldInterleave Time " << Time << " clocks" << std::endl; - } - -# if(GLM_ARCH != GLM_ARCH_PURE) - { - // SIMD - std::vector<__m128i> SimdData(x_max * y_max); - std::vector<__m128i> SimdParam(x_max * y_max); - for(int i = 0; i < SimdParam.size(); ++i) - SimdParam[i] = _mm_set_epi32(i % x_max, 0, i / y_max, 0); - - std::clock_t LastTime = std::clock(); - - for(std::size_t i = 0; i < SimdData.size(); ++i) - SimdData[i] = glm::detail::_mm_bit_interleave_si128(SimdParam[i]); - - std::clock_t Time = std::clock() - LastTime; - - std::cout << "_mm_bit_interleave_si128 Time " << Time << " clocks" << std::endl; - } -# endif//(GLM_ARCH != GLM_ARCH_PURE) - - return 0; - } -} - -namespace bitfieldInterleave3 -{ - template - inline RET refBitfieldInterleave(PARAM x, PARAM y, PARAM z) - { - RET Result = 0; - for(RET i = 0; i < sizeof(PARAM) * 8; ++i) - { - Result |= ((RET(x) & (RET(1U) << i)) << ((i << 1) + 0)); - Result |= ((RET(y) & (RET(1U) << i)) << ((i << 1) + 1)); - Result |= ((RET(z) & (RET(1U) << i)) << ((i << 1) + 2)); - } - return Result; - } - - int test() - { - int Error(0); - - glm::uint16 x_max = 1 << 11; - glm::uint16 y_max = 1 << 11; - glm::uint16 z_max = 1 << 11; - - for(glm::uint16 z = 0; z < z_max; z += 27) - for(glm::uint16 y = 0; y < y_max; y += 27) - for(glm::uint16 x = 0; x < x_max; x += 27) - { - glm::uint64 ResultA = refBitfieldInterleave(x, y, z); - glm::uint64 ResultB = glm::bitfieldInterleave(x, y, z); - Error += ResultA == ResultB ? 0 : 1; - } - - return Error; - } -} - -namespace bitfieldInterleave4 -{ - template - inline RET loopBitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w) - { - RET const v[4] = {x, y, z, w}; - RET Result = 0; - for(RET i = 0; i < sizeof(PARAM) * 8; i++) - { - Result |= ((((v[0] >> i) & 1U)) << ((i << 2) + 0)); - Result |= ((((v[1] >> i) & 1U)) << ((i << 2) + 1)); - Result |= ((((v[2] >> i) & 1U)) << ((i << 2) + 2)); - Result |= ((((v[3] >> i) & 1U)) << ((i << 2) + 3)); - } - return Result; - } - - int test() - { - int Error(0); - - glm::uint16 x_max = 1 << 11; - glm::uint16 y_max = 1 << 11; - glm::uint16 z_max = 1 << 11; - glm::uint16 w_max = 1 << 11; - - for(glm::uint16 w = 0; w < w_max; w += 27) - for(glm::uint16 z = 0; z < z_max; z += 27) - for(glm::uint16 y = 0; y < y_max; y += 27) - for(glm::uint16 x = 0; x < x_max; x += 27) - { - glm::uint64 ResultA = loopBitfieldInterleave(x, y, z, w); - glm::uint64 ResultB = glm::bitfieldInterleave(x, y, z, w); - Error += ResultA == ResultB ? 0 : 1; - } - - return Error; - } -} - -namespace mask -{ - inline int mask_mix(int Bits) - { - return Bits >= 32 ? 0xffffffff : (static_cast(1) << Bits) - static_cast(1); - } - - inline int mask_loop(int Bits) - { - int Mask = 0; - for(int Bit = 0; Bit < Bits; ++Bit) - Mask |= (static_cast(1) << Bit); - return Mask; - } - - int perf() - { - int const Count = 100000000; - - std::clock_t Timestamp1 = std::clock(); - - { - std::vector Mask; - Mask.resize(Count); - for(int i = 0; i < Count; ++i) - Mask[i] = mask_mix(i % 32); - } - - std::clock_t Timestamp2 = std::clock(); - - { - std::vector Mask; - Mask.resize(Count); - for(int i = 0; i < Count; ++i) - Mask[i] = mask_loop(i % 32); - } - - std::clock_t Timestamp3 = std::clock(); - - { - std::vector Mask; - Mask.resize(Count); - for(int i = 0; i < Count; ++i) - Mask[i] = glm::mask(i % 32); - } - - std::clock_t Timestamp4 = std::clock(); - - std::clock_t TimeMix = Timestamp2 - Timestamp1; - std::clock_t TimeLoop = Timestamp3 - Timestamp2; - std::clock_t TimeDefault = Timestamp4 - Timestamp3; - - printf("mask[mix]: %d\n", TimeMix); - printf("mask[loop]: %d\n", TimeLoop); - printf("mask[default]: %d\n", TimeDefault); - - return TimeDefault < TimeLoop ? 0 : 1; - } -}//namespace mask - int main() { int Error(0); - Error += ::mask::perf(); - Error += ::bitfieldInterleave3::test(); - Error += ::bitfieldInterleave4::test(); - Error += ::bitfieldInterleave::test(); Error += ::bitRevert::test(); return Error;