From cf14790806202852f62bcdb6646865c3894913f2 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Sat, 10 Aug 2013 19:52:59 +0200 Subject: [PATCH] Added packF11F11F10 implementation --- glm/gtc/packing.hpp | 4 +- glm/gtc/packing.inl | 116 ++++++++++++++++++++++++++++++++ test/gtc/CMakeLists.txt | 1 + test/gtc/gtc_packing.cpp | 142 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 test/gtc/gtc_packing.cpp diff --git a/glm/gtc/packing.hpp b/glm/gtc/packing.hpp index 0f366384..f77b9f0d 100644 --- a/glm/gtc/packing.hpp +++ b/glm/gtc/packing.hpp @@ -100,8 +100,8 @@ namespace glm GLM_FUNC_DECL uint32 packI3x10I1x2(ivec4 const & v); GLM_FUNC_DECL ivec4 unpackI3x10I1x2(uint32 const & v); - GLM_FUNC_DECL uint32 packU3x10U1x2(uvec4 const & v); - GLM_FUNC_DECL uvec4 unpackU3x10U1x2(uint32 const & v); + GLM_FUNC_DECL uint32 packU10U10U10U2(uvec4 const & v); + GLM_FUNC_DECL uvec4 unpackU10U10U10U2(uint32 const & v); GLM_FUNC_DECL uint32 packF11F11F10(vec3 const & v); GLM_FUNC_DECL vec3 unpackF11F11F10(uint32 const & v); diff --git a/glm/gtc/packing.inl b/glm/gtc/packing.inl index dcaa12f3..2ae8e139 100644 --- a/glm/gtc/packing.inl +++ b/glm/gtc/packing.inl @@ -28,5 +28,121 @@ namespace glm { +namespace detail +{ + glm::uint16 float2half(glm::uint32 const & f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((f >> 16) & 0x8000) | // sign + ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) | // exponential + ((f >> 13) & 0x03ff); // Mantissa + } + + glm::uint16 float2packed11(glm::uint32 const & f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x000007c0 => 00000000 00000000 00000111 11000000 + // 0x00007c00 => 00000000 00000000 01111100 00000000 + // 0x000003ff => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((f & 0x7f800000) - 0x38000000) >> 17) & 0x07c0) | // exponential + ((f >> 17) & 0x003f); // Mantissa + } + + glm::uint float2packed10(glm::uint const & f) + { + // 10 bits => EE EEEFFFFF + // 11 bits => EEE EEFFFFFF + // Half bits => SEEEEEFF FFFFFFFF + // Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF + + // 0x0000001F => 00000000 00000000 00000000 00011111 + // 0x0000003F => 00000000 00000000 00000000 00111111 + // 0x000003E0 => 00000000 00000000 00000011 11100000 + // 0x000007C0 => 00000000 00000000 00000111 11000000 + // 0x00007C00 => 00000000 00000000 01111100 00000000 + // 0x000003FF => 00000000 00000000 00000011 11111111 + // 0x38000000 => 00111000 00000000 00000000 00000000 + // 0x7f800000 => 01111111 10000000 00000000 00000000 + // 0x00008000 => 00000000 00000000 10000000 00000000 + return + ((((f & 0x7f800000) - 0x38000000) >> 18) & 0x03E0) | // exponential + ((f >> 18) & 0x001f); // Mantissa + } + + glm::uint half2float(glm::uint const & h) + { + return ((h & 0x8000) << 16) | ((( h & 0x7c00) + 0x1C000) << 13) | ((h & 0x03FF) << 13); + } + + union uif + { + glm::uint i; + float f; + }; + + glm::uint floatTo11bit(float x) + { + if(x == 0.0f) + return 0; + else if(glm::isnan(x)) + return ~0; + else if(glm::isinf(x)) + return 0x1f << 6; + + uif Union; + Union.f = x; + return float2packed11(Union.i); + } + + glm::uint floatTo10bit(float x) + { + if(x == 0.0f) + return 0; + else if(glm::isnan(x)) + return ~0; + else if(glm::isinf(x)) + return 0x1f << 5; + + uif Union; + Union.f = x; + return float2packed10(Union.i); + } + + glm::uint f11_f11_f10(float x, float y, float z) + { + return ((floatTo11bit(x) & ((1 << 11) - 1)) << 0) | ((floatTo11bit(y) & ((1 << 11) - 1)) << 11) | ((floatTo10bit(z) & ((1 << 10) - 1)) << 22); + } +}//namespace detail + + GLM_FUNC_QUALIFIER uint32 packF11F11F10(vec3 const & v) + { + return + ((detail::floatTo11bit(v.x) & ((1 << 11) - 1)) << 0) | + ((detail::floatTo11bit(v.y) & ((1 << 11) - 1)) << 11) | + ((detail::floatTo10bit(v.z) & ((1 << 10) - 1)) << 22); + } + + GLM_FUNC_QUALIFIER vec3 unpackF11F11F10(uint32 const & v) + { + + } }//namespace glm diff --git a/test/gtc/CMakeLists.txt b/test/gtc/CMakeLists.txt index 273341a8..62c33063 100644 --- a/test/gtc/CMakeLists.txt +++ b/test/gtc/CMakeLists.txt @@ -6,6 +6,7 @@ glmCreateTestGTC(gtc_matrix_integer) glmCreateTestGTC(gtc_matrix_inverse) glmCreateTestGTC(gtc_matrix_transform) glmCreateTestGTC(gtc_noise) +glmCreateTestGTC(gtc_packing) glmCreateTestGTC(gtc_quaternion) glmCreateTestGTC(gtc_random) glmCreateTestGTC(gtc_reciprocal) diff --git a/test/gtc/gtc_packing.cpp b/test/gtc/gtc_packing.cpp new file mode 100644 index 00000000..7eaf5730 --- /dev/null +++ b/test/gtc/gtc_packing.cpp @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////////// +/// OpenGL Mathematics (glm.g-truc.net) +/// +/// Copyright (c) 2005 - 2013 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 test +/// @file test/gtc/packing.cpp +/// @date 2013-08-09 / 2013-08-09 +/// @author Christophe Riccio +/////////////////////////////////////////////////////////////////////////////////// + + +#include +#include + +void print_bits(glm::half const & s) +{ + union + { + glm::detail::hdata h; + unsigned short i; + } uif; + + uif.h = s._data(); + + printf("f16: "); + for(std::size_t j = sizeof(s) * 8; j > 0; --j) + { + if(j == 10 || j == 15) + printf(" "); + printf("%d", (uif.i & (1 << (j - 1))) ? 1 : 0); + } +} + +void print_bits(float const & s) +{ + union + { + float f; + unsigned int i; + } uif; + + uif.f = s; + + printf("f32: "); + for(std::size_t j = sizeof(s) * 8; j > 0; --j) + { + if(j == 23 || j == 31) + printf(" "); + printf("%d", (uif.i & (1 << (j - 1))) ? 1 : 0); + } +} + +void print_10bits(glm::uint const & s) +{ + printf("10b: "); + for(std::size_t j = 10; j > 0; --j) + { + if(j == 5) + printf(" "); + printf("%d", (s & (1 << (j - 1))) ? 1 : 0); + } +} + +void print_11bits(glm::uint const & s) +{ + printf("11b: "); + for(std::size_t j = 11; j > 0; --j) + { + if(j == 6) + printf(" "); + printf("%d", (s & (1 << (j - 1))) ? 1 : 0); + } +} + +void print_value(float const & s) +{ + printf("%2.5f, ", s); + print_bits(s); + printf(", "); + print_bits(glm::half(s)); + printf(", "); + print_11bits(detail::floatTo11bit(s)); + printf(", "); + print_10bits(detail::floatTo10bit(s)); + printf("\n"); +} + +int test_half() +{ + int Error = 0; + + print_value(0.0); + print_value(0.1); + print_value(0.2); + print_value(0.3); + print_value(0.4); + print_value(0.5); + print_value(0.6); + print_value(1.0); + print_value(1.1); + print_value(1.2); + print_value(1.3); + print_value(1.4); + print_value(1.5); + print_value(1.6); + print_value(2.0); + print_value(2.1); + print_value(2.2); + print_value(2.3); + print_value(2.4); + print_value(2.5); + print_value(2.6); + + return Error; +} + +int main() +{ + int Error(0); + + Error += test_half(); + + return Error; +}