From 5459e93446d1c752d61ec2564b42d6057c5312e0 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sun, 26 Mar 2017 23:51:13 +0200 Subject: [PATCH] Added bitfield interleave implementation --- test/gtc/gtc_bitfield.cpp | 180 +++++++++++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 1 deletion(-) diff --git a/test/gtc/gtc_bitfield.cpp b/test/gtc/gtc_bitfield.cpp index a9346b7a..a6ced248 100644 --- a/test/gtc/gtc_bitfield.cpp +++ b/test/gtc/gtc_bitfield.cpp @@ -623,10 +623,188 @@ namespace bitfieldInterleave } }//namespace bitfieldInterleave +namespace bitfieldInterleave5 +{ + GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave_u8vec2(glm::uint8 x, glm::uint8 y) + { + glm::uint32 Result = (glm::uint32(y) << 16) | glm::uint32(x); + Result = ((Result << 4) | Result) & glm::uint32(0x0F0F0F0F); + Result = ((Result << 2) | Result) & glm::uint32(0x33333333); + Result = ((Result << 1) | Result) & glm::uint32(0x55555555); + return static_cast((Result & 0x0000FFFF) | (Result >> 15)); + } + + GLM_FUNC_QUALIFIER glm::u8vec2 bitfieldDeinterleave_u8vec2(glm::uint16 InterleavedBitfield) + { + glm::uint32 Result(InterleavedBitfield); + Result = ((Result << 15) | Result) & 0x55555555; + Result = ((Result >> 1) | Result) & glm::uint32(0x33333333); + Result = ((Result >> 2) | Result) & glm::uint32(0x0F0F0F0F); + Result = ((Result >> 4) | Result) & glm::uint32(0x00FF00FF); + return glm::u8vec2(Result & 0x0000FFFF, Result >> 16); + } + + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave_u8vec4(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w) + { + glm::uint64 Result = (glm::uint64(w) << 48) | (glm::uint64(z) << 32) | (glm::uint64(y) << 16) | glm::uint64(x); + Result = ((Result << 4) | Result) & 0x0F0F0F0F0F0F0F0Full; + Result = ((Result << 2) | Result) & 0x3333333333333333ull; + Result = ((Result << 1) | Result) & 0x5555555555555555ull; + return static_cast((Result & 0x0000FFFF) | (Result >> 15)); + } + + GLM_FUNC_QUALIFIER glm::u8vec4 bitfieldDeinterleave_u8vec4(glm::uint32 InterleavedBitfield) + { + glm::uint64 Result(InterleavedBitfield); + Result = ((Result << 15) | Result) & 0x5555555555555555ull; + Result = ((Result >> 1) | Result) & 0x3333333333333333ull; + Result = ((Result >> 2) | Result) & 0x0F0F0F0F0F0F0F0Full; + Result = ((Result >> 4) | Result) & 0x00FF00FF00FF00FFull; + return glm::u8vec4( + (Result >> 0) & 0x000000000000FFFFull, + (Result >> 16) & 0x00000000FFFF0000ull, + (Result >> 32) & 0x0000FFFF00000000ull, + (Result >> 48) & 0xFFFF000000000000ull); + } + + GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave_u16vec2(glm::uint16 x, glm::uint16 y) + { + glm::uint64 Result = (glm::uint64(y) << 32) | glm::uint64(x); + Result = ((Result << 8) | Result) & glm::uint32(0x00FF00FF00FF00FFull); + Result = ((Result << 4) | Result) & glm::uint32(0x0F0F0F0F0F0F0F0Full); + Result = ((Result << 2) | Result) & glm::uint32(0x3333333333333333ull); + Result = ((Result << 1) | Result) & glm::uint32(0x5555555555555555ull); + return static_cast((Result & 0x00000000FFFFFFFFull) | (Result >> 31)); + } + + GLM_FUNC_QUALIFIER glm::u16vec2 bitfieldDeinterleave_u16vec2(glm::uint32 InterleavedBitfield) + { + glm::uint64 Result(InterleavedBitfield); + Result = ((Result << 31) | Result) & 0x5555555555555555ull; + Result = ((Result >> 1) | Result) & 0x3333333333333333ull; + Result = ((Result >> 2) | Result) & 0x0F0F0F0F0F0F0F0Full; + Result = ((Result >> 4) | Result) & 0x00FF00FF00FF00FFull; + Result = ((Result >> 8) | Result) & 0x0000FFFF0000FFFFull; + return glm::u16vec2(Result & 0x00000000FFFFFFFFull, Result >> 32); + } + + int test() + { + int Error = 0; + + for(glm::size_t j = 0; j < 256; ++j) + for(glm::size_t i = 0; i < 256; ++i) + { + glm::uint16 A = bitfieldInterleave_u8vec2(glm::uint8(i), glm::uint8(j)); + glm::uint16 B = glm::bitfieldInterleave(glm::uint8(i), glm::uint8(j)); + Error += A == B ? 0 : 1; + + glm::u8vec2 C = bitfieldDeinterleave_u8vec2(A); + Error += C.x == glm::uint8(i) ? 0 : 1; + Error += C.y == glm::uint8(j) ? 0 : 1; + } + + for(glm::size_t j = 0; j < 256; ++j) + for(glm::size_t i = 0; i < 256; ++i) + { + glm::uint32 A = bitfieldInterleave_u16vec2(glm::uint16(i), glm::uint16(j)); + glm::u8vec2 C = bitfieldDeinterleave_u8vec2(A); + Error += C.x == glm::uint8(i) ? 0 : 1; + Error += C.y == glm::uint8(j) ? 0 : 1; + } + + return Error; + } + + int perf_old_u8vec2(std::vector& Result) + { + int Error = 0; + + const std::clock_t BeginTime = std::clock(); + + for(glm::size_t k = 0; k < 10000; ++k) + for(glm::size_t j = 0; j < 256; ++j) + for(glm::size_t i = 0; i < 256; ++i) + Error += Result[j * 256 + i] == glm::bitfieldInterleave(glm::uint8(i), glm::uint8(j)) ? 0 : 1; + + const std::clock_t EndTime = std::clock(); + + std::printf("glm::bitfieldInterleave Time %d clocks\n", static_cast(EndTime - BeginTime)); + + return Error; + } + + int perf_new_u8vec2(std::vector& Result) + { + int Error = 0; + + const std::clock_t BeginTime = std::clock(); + + for(glm::size_t k = 0; k < 10000; ++k) + for(glm::size_t j = 0; j < 256; ++j) + for(glm::size_t i = 0; i < 256; ++i) + Error += Result[j * 256 + i] == bitfieldInterleave_u8vec2(glm::uint8(i), glm::uint8(j)) ? 0 : 1; + + const std::clock_t EndTime = std::clock(); + + std::printf("bitfieldInterleave_u8vec2 Time %d clocks\n", static_cast(EndTime - BeginTime)); + + return Error; + } + + int perf_new_u16vec2(std::vector& Result) + { + int Error = 0; + + const std::clock_t BeginTime = std::clock(); + + for(glm::size_t k = 0; k < 10000; ++k) + for(glm::size_t j = 0; j < 256; ++j) + for(glm::size_t i = 0; i < 256; ++i) + Error += Result[j * 256 + i] == bitfieldInterleave_u16vec2(glm::uint16(i), glm::uint16(j)) ? 0 : 1; + + const std::clock_t EndTime = std::clock(); + + std::printf("bitfieldInterleave_u16vec2 Time %d clocks\n", static_cast(EndTime - BeginTime)); + + return Error; + } + + int perf() + { + int Error = 0; + + std::printf("bitfieldInterleave perf: init\r"); + + std::vector Result_u8vec2(256 * 256, 0); + for(glm::size_t j = 0; j < 256; ++j) + for(glm::size_t i = 0; i < 256; ++i) + Result_u8vec2[j * 256 + i] = glm::bitfieldInterleave(glm::uint8(i), glm::uint8(j)); + + Error += perf_old_u8vec2(Result_u8vec2); + Error += perf_new_u8vec2(Result_u8vec2); + + std::vector Result_u16vec2(256 * 256, 0); + for(glm::size_t j = 0; j < 256; ++j) + for(glm::size_t i = 0; i < 256; ++i) + Result_u16vec2[j * 256 + i] = glm::bitfieldInterleave(glm::uint16(i), glm::uint16(j)); + + Error += perf_new_u16vec2(Result_u16vec2); + + std::printf("bitfieldInterleave perf: %d Errors\n", Error); + + return Error; + } + +}//namespace bitfieldInterleave5 + int main() { int Error(0); + Error += ::bitfieldInterleave5::test(); + Error += ::bitfieldInterleave5::perf(); +/* Error += ::mask::test(); Error += ::bitfieldInterleave3::test(); Error += ::bitfieldInterleave4::test(); @@ -637,6 +815,6 @@ int main() Error += ::mask::perf(); Error += ::bitfieldInterleave::perf(); # endif//NDEBUG - +*/ return Error; }