parent
1b6b8183a0
commit
087d6292e3
9 changed files with 1216 additions and 1202 deletions
@ -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
|
||||
///
|
||||
/// <glm/gtc/bitfield.hpp> 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 <precision P, template <typename, precision> class vecType> |
||||
GLM_FUNC_DECL vecType<int, P> mask(vecType<int, P> const & v); |
||||
|
||||
/// Rotate all bits to the right.
|
||||
/// @see gtc_bitfield
|
||||
template <typename genType> |
||||
GLM_FUNC_DECL genType bitRotateRight(genType In, int Shift); |
||||
|
||||
/// Rotate all bits to the left.
|
||||
/// @see gtc_bitfield
|
||||
template <typename genType> |
||||
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" |
@ -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 <typename PARAM, typename RET> |
||||
GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y); |
||||
|
||||
template <typename PARAM, typename RET> |
||||
GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z); |
||||
|
||||
template <typename PARAM, typename RET> |
||||
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<int>(0) : (static_cast<int>(1) << Bits) - static_cast<int>(1); |
||||
} |
||||
|
||||
template <precision P, template <typename, precision> class vecType> |
||||
GLM_FUNC_QUALIFIER vecType<int, P> mask(vecType<int, P> const & v) |
||||
{ |
||||
return detail::functor1<int, int, P, vecType>::call(mask, v); |
||||
} |
||||
|
||||
template <typename genType> |
||||
GLM_FUNC_QUALIFIER genType bitRotateRight(genType In, int Shift) |
||||
{ |
||||
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values"); |
||||
|
||||
int const BitSize = static_cast<genType>(sizeof(T) * 8); |
||||
return (In << static_cast<T>(Shift)) | (In >> static_cast<T>(BitSize - Shift)); |
||||
} |
||||
|
||||
template <typename T, precision P, template <typename, precision> class vecType> |
||||
GLM_FUNC_QUALIFIER vecType<T, P> bitRotateRight(vecType<T, P> const & Value, int Shift) |
||||
{ |
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitRotateRight' only accept integer values"); |
||||
|
||||
int const BitSize = static_cast<int>(sizeof(T) * 8); |
||||
return (In << static_cast<T>(Shift)) | (In >> static_cast<T>(BitSize - Shift)); |
||||
} |
||||
|
||||
template <typename genType> |
||||
GLM_FUNC_QUALIFIER genType bitRotateLeft(genType In, int Shift) |
||||
{ |
||||
GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values"); |
||||
|
||||
int const BitSize = static_cast<genType>(sizeof(T) * 8); |
||||
return (In >> static_cast<genType>(Shift)) | (In << static_cast<genType>(BitSize - Shift)); |
||||
} |
||||
|
||||
template <typename T, precision P, template <typename, precision> class vecType> |
||||
GLM_FUNC_QUALIFIER vecType<T, P> bitRotateLeft(vecType<T, P> const & In, int Shift) |
||||
{ |
||||
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitRotateLeft' only accept integer values"); |
||||
|
||||
int const BitSize = static_cast<int>(sizeof(T) * 8); |
||||
return (In >> static_cast<T>(Shift)) | (In << static_cast<T>(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<uint8, uint16>(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<uint16, uint32>(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<uint32, uint64>(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<uint8, uint32>(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<uint32, uint64>(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<uint32, uint64>(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<uint8, uint32>(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<uint16, uint64>(x, y, z, w); |
||||
} |
||||
}//namespace glm |
@ -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 <glm/gtc/bitfield.hpp> |
||||
#include <glm/gtc/type_precision.hpp> |
||||
//#include <glm/vec2.hpp>
|
||||
#include <ctime> |
||||
#include <cstdio> |
||||
#include <vector> |
||||
|
||||
namespace mask |
||||
{ |
||||
inline int mask_mix(int Bits) |
||||
{ |
||||
return Bits >= 32 ? 0xffffffff : (static_cast<int>(1) << Bits) - static_cast<int>(1); |
||||
} |
||||
|
||||
inline int mask_loop(int Bits) |
||||
{ |
||||
int Mask = 0; |
||||
for(int Bit = 0; Bit < Bits; ++Bit) |
||||
Mask |= (static_cast<int>(1) << Bit); |
||||
return Mask; |
||||
} |
||||
|
||||
int perf() |
||||
{ |
||||
int const Count = 100000000; |
||||
|
||||
std::clock_t Timestamp1 = std::clock(); |
||||
|
||||
{ |
||||
std::vector<int> 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<int> 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<int> 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 <typename PARAM, typename RET> |
||||
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<glm::uint16, glm::uint64>(x, y, z); |
||||
glm::uint64 ResultB = glm::bitfieldInterleave(x, y, z); |
||||
Error += ResultA == ResultB ? 0 : 1; |
||||
} |
||||
|
||||
return Error; |
||||
} |
||||
} |
||||
|
||||
namespace bitfieldInterleave4 |
||||
{ |
||||
template <typename PARAM, typename RET> |
||||
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<glm::uint16, glm::uint64>(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<glm::uint64> Data(x_max * y_max); |
||||
std::vector<glm::u32vec2> 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; |
||||
} |
Loading…
Reference in New Issue