mirror of
https://github.com/g-truc/glm.git
synced 2024-11-26 02:04:35 +00:00
Added bitfieldDeinterleave with tests
This commit is contained in:
parent
f5572344f5
commit
b4981e56fa
@ -19,6 +19,7 @@
|
|||||||
#include "../detail/qualifier.hpp"
|
#include "../detail/qualifier.hpp"
|
||||||
#include "../detail/type_int.hpp"
|
#include "../detail/type_int.hpp"
|
||||||
#include "../detail/_vectorize.hpp"
|
#include "../detail/_vectorize.hpp"
|
||||||
|
#include "type_precision.hpp"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED)
|
#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED)
|
||||||
@ -124,6 +125,18 @@ namespace glm
|
|||||||
/// @see gtc_bitfield
|
/// @see gtc_bitfield
|
||||||
GLM_FUNC_DECL uint16 bitfieldInterleave(uint8 x, uint8 y);
|
GLM_FUNC_DECL uint16 bitfieldInterleave(uint8 x, uint8 y);
|
||||||
|
|
||||||
|
/// Interleaves the bits of x and y.
|
||||||
|
/// The first bit is the first bit of v.x followed by the first bit of v.y.
|
||||||
|
/// The other bits are interleaved following the previous sequence.
|
||||||
|
///
|
||||||
|
/// @see gtc_bitfield
|
||||||
|
GLM_FUNC_DECL uint16 bitfieldInterleave(u8vec2 const& v);
|
||||||
|
|
||||||
|
/// Deinterleaves the bits of x.
|
||||||
|
///
|
||||||
|
/// @see gtc_bitfield
|
||||||
|
GLM_FUNC_DECL glm::u8vec2 bitfieldDeinterleave(glm::uint16 x);
|
||||||
|
|
||||||
/// Interleaves the bits of x and 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 first bit is the first bit of x followed by the first bit of y.
|
||||||
/// The other bits are interleaved following the previous sequence.
|
/// The other bits are interleaved following the previous sequence.
|
||||||
@ -138,6 +151,18 @@ namespace glm
|
|||||||
/// @see gtc_bitfield
|
/// @see gtc_bitfield
|
||||||
GLM_FUNC_DECL uint32 bitfieldInterleave(uint16 x, uint16 y);
|
GLM_FUNC_DECL uint32 bitfieldInterleave(uint16 x, uint16 y);
|
||||||
|
|
||||||
|
/// Interleaves the bits of x and y.
|
||||||
|
/// The first bit is the first bit of v.x followed by the first bit of v.y.
|
||||||
|
/// The other bits are interleaved following the previous sequence.
|
||||||
|
///
|
||||||
|
/// @see gtc_bitfield
|
||||||
|
GLM_FUNC_DECL uint32 bitfieldInterleave(u16vec2 const& v);
|
||||||
|
|
||||||
|
/// Deinterleaves the bits of x.
|
||||||
|
///
|
||||||
|
/// @see gtc_bitfield
|
||||||
|
GLM_FUNC_DECL glm::u16vec2 bitfieldDeinterleave(glm::uint32 x);
|
||||||
|
|
||||||
/// Interleaves the bits of x and 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 first bit is the first bit of x followed by the first bit of y.
|
||||||
/// The other bits are interleaved following the previous sequence.
|
/// The other bits are interleaved following the previous sequence.
|
||||||
@ -152,6 +177,18 @@ namespace glm
|
|||||||
/// @see gtc_bitfield
|
/// @see gtc_bitfield
|
||||||
GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y);
|
GLM_FUNC_DECL uint64 bitfieldInterleave(uint32 x, uint32 y);
|
||||||
|
|
||||||
|
/// Interleaves the bits of x and y.
|
||||||
|
/// The first bit is the first bit of v.x followed by the first bit of v.y.
|
||||||
|
/// The other bits are interleaved following the previous sequence.
|
||||||
|
///
|
||||||
|
/// @see gtc_bitfield
|
||||||
|
GLM_FUNC_DECL uint64 bitfieldInterleave(u32vec2 const& v);
|
||||||
|
|
||||||
|
/// Deinterleaves the bits of x.
|
||||||
|
///
|
||||||
|
/// @see gtc_bitfield
|
||||||
|
GLM_FUNC_DECL glm::u32vec2 bitfieldDeinterleave(glm::uint64 x);
|
||||||
|
|
||||||
/// Interleaves the bits of x, y and 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 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.
|
/// The other bits are interleaved following the previous sequence.
|
||||||
|
@ -324,6 +324,34 @@ namespace detail
|
|||||||
return detail::bitfieldInterleave<uint8, uint16>(x, y);
|
return detail::bitfieldInterleave<uint8, uint16>(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(u8vec2 const& v)
|
||||||
|
{
|
||||||
|
return detail::bitfieldInterleave<uint8, uint16>(v.x, v.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLM_FUNC_QUALIFIER u8vec2 bitfieldDeinterleave(glm::uint16 x)
|
||||||
|
{
|
||||||
|
uint16 REG1(x);
|
||||||
|
uint16 REG2(x >>= 1);
|
||||||
|
|
||||||
|
REG1 = REG1 & static_cast<uint16>(0x5555555555555555ull);
|
||||||
|
REG2 = REG2 & static_cast<uint16>(0x5555555555555555ull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 1) | REG1) & static_cast<uint16>(0x3333333333333333ull);
|
||||||
|
REG2 = ((REG2 >> 1) | REG2) & static_cast<uint16>(0x3333333333333333ull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 2) | REG1) & static_cast<uint16>(0x0F0F0F0F0F0F0F0Full);
|
||||||
|
REG2 = ((REG2 >> 2) | REG2) & static_cast<uint16>(0x0F0F0F0F0F0F0F0Full);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 4) | REG1) & static_cast<uint16>(0x00FF00FF00FF00FFull);
|
||||||
|
REG2 = ((REG2 >> 4) | REG2) & static_cast<uint16>(0x00FF00FF00FF00FFull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 8) | REG1) & static_cast<uint16>(0x0000FFFF0000FFFFull);
|
||||||
|
REG2 = ((REG2 >> 8) | REG2) & static_cast<uint16>(0x0000FFFF0000FFFFull);
|
||||||
|
|
||||||
|
return glm::u8vec2(REG1, REG2);
|
||||||
|
}
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y)
|
GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y)
|
||||||
{
|
{
|
||||||
union sign16
|
union sign16
|
||||||
@ -350,6 +378,34 @@ namespace detail
|
|||||||
return detail::bitfieldInterleave<uint16, uint32>(x, y);
|
return detail::bitfieldInterleave<uint16, uint32>(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(u16vec2 const& v)
|
||||||
|
{
|
||||||
|
return detail::bitfieldInterleave<uint16, uint32>(v.x, v.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLM_FUNC_QUALIFIER glm::u16vec2 bitfieldDeinterleave(glm::uint32 x)
|
||||||
|
{
|
||||||
|
glm::uint32 REG1(x);
|
||||||
|
glm::uint32 REG2(x >>= 1);
|
||||||
|
|
||||||
|
REG1 = REG1 & static_cast<glm::uint32>(0x5555555555555555ull);
|
||||||
|
REG2 = REG2 & static_cast<glm::uint32>(0x5555555555555555ull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 1) | REG1) & static_cast<glm::uint32>(0x3333333333333333ull);
|
||||||
|
REG2 = ((REG2 >> 1) | REG2) & static_cast<glm::uint32>(0x3333333333333333ull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 2) | REG1) & static_cast<glm::uint32>(0x0F0F0F0F0F0F0F0Full);
|
||||||
|
REG2 = ((REG2 >> 2) | REG2) & static_cast<glm::uint32>(0x0F0F0F0F0F0F0F0Full);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 4) | REG1) & static_cast<glm::uint32>(0x00FF00FF00FF00FFull);
|
||||||
|
REG2 = ((REG2 >> 4) | REG2) & static_cast<glm::uint32>(0x00FF00FF00FF00FFull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 8) | REG1) & static_cast<glm::uint32>(0x0000FFFF0000FFFFull);
|
||||||
|
REG2 = ((REG2 >> 8) | REG2) & static_cast<glm::uint32>(0x0000FFFF0000FFFFull);
|
||||||
|
|
||||||
|
return glm::u16vec2(REG1, REG2);
|
||||||
|
}
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y)
|
GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y)
|
||||||
{
|
{
|
||||||
union sign32
|
union sign32
|
||||||
@ -376,6 +432,37 @@ namespace detail
|
|||||||
return detail::bitfieldInterleave<uint32, uint64>(x, y);
|
return detail::bitfieldInterleave<uint32, uint64>(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(u32vec2 const& v)
|
||||||
|
{
|
||||||
|
return detail::bitfieldInterleave<uint32, uint64>(v.x, v.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLM_FUNC_QUALIFIER glm::u32vec2 bitfieldDeinterleave(glm::uint64 x)
|
||||||
|
{
|
||||||
|
glm::uint64 REG1(x);
|
||||||
|
glm::uint64 REG2(x >>= 1);
|
||||||
|
|
||||||
|
REG1 = REG1 & static_cast<glm::uint64>(0x5555555555555555ull);
|
||||||
|
REG2 = REG2 & static_cast<glm::uint64>(0x5555555555555555ull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 1) | REG1) & static_cast<glm::uint64>(0x3333333333333333ull);
|
||||||
|
REG2 = ((REG2 >> 1) | REG2) & static_cast<glm::uint64>(0x3333333333333333ull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 2) | REG1) & static_cast<glm::uint64>(0x0F0F0F0F0F0F0F0Full);
|
||||||
|
REG2 = ((REG2 >> 2) | REG2) & static_cast<glm::uint64>(0x0F0F0F0F0F0F0F0Full);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 4) | REG1) & static_cast<glm::uint64>(0x00FF00FF00FF00FFull);
|
||||||
|
REG2 = ((REG2 >> 4) | REG2) & static_cast<glm::uint64>(0x00FF00FF00FF00FFull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 8) | REG1) & static_cast<glm::uint64>(0x0000FFFF0000FFFFull);
|
||||||
|
REG2 = ((REG2 >> 8) | REG2) & static_cast<glm::uint64>(0x0000FFFF0000FFFFull);
|
||||||
|
|
||||||
|
REG1 = ((REG1 >> 16) | REG1) & static_cast<glm::uint64>(0x00000000FFFFFFFFull);
|
||||||
|
REG2 = ((REG2 >> 16) | REG2) & static_cast<glm::uint64>(0x00000000FFFFFFFFull);
|
||||||
|
|
||||||
|
return glm::u32vec2(REG1, REG2);
|
||||||
|
}
|
||||||
|
|
||||||
GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z)
|
GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z)
|
||||||
{
|
{
|
||||||
union sign8
|
union sign8
|
||||||
|
@ -51,6 +51,10 @@ glm::mat4 camera(float Translate, glm::vec2 const& Rotate)
|
|||||||
|
|
||||||
## Release notes
|
## Release notes
|
||||||
|
|
||||||
|
### [GLM 0.9.9.1](https://github.com/g-truc/glm/commits/master) - 2018-0X-XX
|
||||||
|
#### Features:
|
||||||
|
- Added bitfieldDeinterleave to GTC_bitfield
|
||||||
|
|
||||||
### [GLM 0.9.9.0](https://github.com/g-truc/glm/releases/tag/0.9.9.0) - 2018-05-22
|
### [GLM 0.9.9.0](https://github.com/g-truc/glm/releases/tag/0.9.9.0) - 2018-05-22
|
||||||
#### Features:
|
#### Features:
|
||||||
- Added RGBM encoding in GTC_packing #420
|
- Added RGBM encoding in GTC_packing #420
|
||||||
|
@ -289,6 +289,62 @@ namespace min_
|
|||||||
|
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int min_tern(int a, int b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int min_int(int x, int y)
|
||||||
|
{
|
||||||
|
return y ^ ((x ^ y) & -(x < y));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int perf(int Count)
|
||||||
|
{
|
||||||
|
std::vector<int> A(Count);
|
||||||
|
std::vector<int> B(Count);
|
||||||
|
|
||||||
|
std::size_t const InternalCount = 200000;
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i < Count; ++i)
|
||||||
|
{
|
||||||
|
A[i] = glm::linearRand(-1000, 1000);
|
||||||
|
B[i] = glm::linearRand(-1000, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Error = 0;
|
||||||
|
|
||||||
|
glm::int32 SumA = 0;
|
||||||
|
{
|
||||||
|
std::clock_t Timestamp0 = std::clock();
|
||||||
|
|
||||||
|
for (std::size_t j = 0; j < InternalCount; ++j)
|
||||||
|
for (std::size_t i = 0; i < Count; ++i)
|
||||||
|
SumA += min_tern(A[i], B[i]);
|
||||||
|
|
||||||
|
std::clock_t Timestamp1 = std::clock();
|
||||||
|
|
||||||
|
std::printf("min_tern Time %d clocks\n", static_cast<unsigned int>(Timestamp1 - Timestamp0));
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::int32 SumB = 0;
|
||||||
|
{
|
||||||
|
std::clock_t Timestamp0 = std::clock();
|
||||||
|
|
||||||
|
for (std::size_t j = 0; j < InternalCount; ++j)
|
||||||
|
for (std::size_t i = 0; i < Count; ++i)
|
||||||
|
SumB += min_int(A[i], B[i]);
|
||||||
|
|
||||||
|
std::clock_t Timestamp1 = std::clock();
|
||||||
|
|
||||||
|
std::printf("min_int Time %d clocks\n", static_cast<unsigned int>(Timestamp1 - Timestamp0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Error += SumA == SumB ? 0 : 1;
|
||||||
|
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
}//namespace min_
|
}//namespace min_
|
||||||
|
|
||||||
namespace max_
|
namespace max_
|
||||||
@ -1262,6 +1318,8 @@ int main()
|
|||||||
# endif
|
# endif
|
||||||
Error += sign::perf(Samples);
|
Error += sign::perf(Samples);
|
||||||
|
|
||||||
|
Error += min_::perf(Samples);
|
||||||
|
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,19 +493,29 @@ namespace bitfieldInterleave
|
|||||||
for(glm::uint8 y = 0; y < 127; ++y)
|
for(glm::uint8 y = 0; y < 127; ++y)
|
||||||
for(glm::uint8 x = 0; x < 127; ++x)
|
for(glm::uint8 x = 0; x < 127; ++x)
|
||||||
{
|
{
|
||||||
glm::uint64 A(glm::bitfieldInterleave(glm::uint8(x), glm::uint8(y)));
|
glm::uint64 A(glm::bitfieldInterleave(glm::u8vec2(x, y)));
|
||||||
glm::uint64 B(glm::bitfieldInterleave(glm::uint16(x), glm::uint16(y)));
|
glm::uint64 B(glm::bitfieldInterleave(glm::u16vec2(x, y)));
|
||||||
glm::uint64 C(glm::bitfieldInterleave(glm::uint32(x), glm::uint32(y)));
|
glm::uint64 C(glm::bitfieldInterleave(glm::u32vec2(x, y)));
|
||||||
|
|
||||||
Error += A == B ? 0 : 1;
|
Error += A == B ? 0 : 1;
|
||||||
Error += A == C ? 0 : 1;
|
Error += A == C ? 0 : 1;
|
||||||
|
|
||||||
glm::int64 D(glm::bitfieldInterleave(glm::int8(x), glm::int8(y)));
|
glm::u32vec2 const& D = glm::bitfieldDeinterleave(C);
|
||||||
glm::int64 E(glm::bitfieldInterleave(glm::int16(x), glm::int16(y)));
|
Error += D.x == x ? 0 : 1;
|
||||||
glm::int64 F(glm::bitfieldInterleave(glm::int32(x), glm::int32(y)));
|
Error += D.y == y ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Error += D == E ? 0 : 1;
|
{
|
||||||
Error += D == F ? 0 : 1;
|
for(glm::uint8 y = 0; y < 127; ++y)
|
||||||
|
for(glm::uint8 x = 0; x < 127; ++x)
|
||||||
|
{
|
||||||
|
glm::int64 A(glm::bitfieldInterleave(glm::int8(x), glm::int8(y)));
|
||||||
|
glm::int64 B(glm::bitfieldInterleave(glm::int16(x), glm::int16(y)));
|
||||||
|
glm::int64 C(glm::bitfieldInterleave(glm::int32(x), glm::int32(y)));
|
||||||
|
|
||||||
|
Error += A == B ? 0 : 1;
|
||||||
|
Error += A == C ? 0 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,6 +898,7 @@ namespace bitfieldInterleave5
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int Error = 0;
|
int Error = 0;
|
||||||
|
|
||||||
/* Tests for a faster and to reserve bitfieldInterleave
|
/* Tests for a faster and to reserve bitfieldInterleave
|
||||||
Error += ::bitfieldInterleave5::test();
|
Error += ::bitfieldInterleave5::test();
|
||||||
Error += ::bitfieldInterleave5::perf();
|
Error += ::bitfieldInterleave5::perf();
|
||||||
|
Loading…
Reference in New Issue
Block a user