Browse Source

core: start working on the "half" type.

legacy
Sam Hocevar sam 13 years ago
parent
commit
96007d26c4
4 changed files with 169 additions and 1 deletions
  1. +1
    -1
      src/Makefile.am
  2. +1
    -0
      src/core.h
  3. +96
    -0
      src/half.cpp
  4. +71
    -0
      src/half.h

+ 1
- 1
src/Makefile.am View File

@@ -9,7 +9,7 @@ liblol_a_SOURCES = \
timer.cpp timer.h bitfield.h profiler.cpp profiler.h input.h input.cpp \ timer.cpp timer.h bitfield.h profiler.cpp profiler.h input.h input.cpp \
world.cpp world.h sample.cpp sample.h sampler.cpp sampler.h \ world.cpp world.h sample.cpp sample.h sampler.cpp sampler.h \
text.cpp text.h emitter.cpp emitter.h numeric.h hash.cpp hash.h \ text.cpp text.h emitter.cpp emitter.h numeric.h hash.cpp hash.h \
worldentity.cpp worldentity.h gradient.cpp gradient.h \
worldentity.cpp worldentity.h gradient.cpp gradient.h half.cpp half.h \
platform.cpp platform.h sprite.cpp sprite.h \ platform.cpp platform.h sprite.cpp sprite.h \
\ \
eglapp.cpp eglapp.h \ eglapp.cpp eglapp.h \


+ 1
- 0
src/core.h View File

@@ -19,6 +19,7 @@
// Base types // Base types
#include "matrix.h" #include "matrix.h"
#include "numeric.h" #include "numeric.h"
#include "half.h"
#include "timer.h" #include "timer.h"


// Static classes // Static classes


+ 96
- 0
src/half.cpp View File

@@ -0,0 +1,96 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/projects/COPYING.WTFPL for more details.
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include "core.h"

using namespace std;

#define S4(x) S1(4*(x)), S1(4*(x)+1), S1(4*(x)+2), S1(4*(x)+3)
#define S16(x) S4(4*(x)), S4(4*(x)+1), S4(4*(x)+2), S4(4*(x)+3)
#define S64(x) S16(4*(x)), S16(4*(x)+1), S16(4*(x)+2), S16(4*(x)+3)
#define S256(x) S64(4*(x)), S64(4*(x)+1), S64(4*(x)+2), S64(4*(x)+3)

namespace lol
{

half half::makefast(float f)
{
/* Lookup table-based algorithm from “Fast Half Float Conversions”
* by Jeroen van der Zijp, November 2008. No rounding is performed. */
static uint16_t const basetable[512] =
{
#define S1(i) (((i) < 103) ? 0x0000: \
((i) < 113) ? 0x0400 >> (113 - (i)) : \
((i) < 143) ? ((i) - 112) << 10 : 0x7c00)
S256(0),
#undef S1
#define S1(i) (0x8000 | (((i) < 103) ? 0x0000 : \
((i) < 113) ? 0x0400 >> (113 - (i)): \
((i) < 143) ? ((i) - 112) << 10 : 0x7c00))
S256(0),
#undef S1
};

static uint8_t const shifttable[512] =
{
#define S1(i) (((i) < 103) ? 24 : \
((i) < 113) ? 126 - (i) : \
((i) < 143 || (i) == 255) ? 13 : 24)
S256(0), S256(0),
#undef S1
};

union { float f; uint32_t x; } u = { f };

uint16_t bits = basetable[(u.x >> 23) & 0x1ff];
bits |= (u.x & 0x007fffff) >> shifttable[(u.x >> 23) & 0x1ff];
return makebits(bits);
}

half half::makeslow(float f)
{
union { float f; uint32_t x; } u = { f };

uint16_t bits = (u.x >> 16) & 0x8000; /* Get the sign */
uint16_t m = (u.x >> 12) & 0x07ff; /* Keep one extra bit for rounding */
unsigned int e = (u.x >> 23) & 0xff; /* Using int is faster here */

/* If zero, or denormal, or exponent underflows too much for a denormal,
* return signed zero */
if (e < 103)
return makebits(bits);

/* If NaN, Inf or exponent overflow, return NaN or Inf */
if (e > 142)
{
bits |= 0x7c00u;
bits |= e == 255 && (u.x & 0x007fffffu);
return makebits(bits);
}

/* If exponent underflows but not too much, return a denormal */
if (e < 113)
{
m |= 0x0800u;
bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
return makebits(bits);
}

bits |= ((e - 112) << 10) | (m >> 1);
bits += m & 1; /* Overflows here are expected and handled */
return makebits(bits);
}

} /* namespace lol */


+ 71
- 0
src/half.h View File

@@ -0,0 +1,71 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/projects/COPYING.WTFPL for more details.
//

//
// The Half class
// --------------
//

#if !defined __LOL_HALF_H__
#define __LOL_HALF_H__

#include <stdint.h>

namespace lol
{

class half
{
private:
uint16_t m_bits;

public:
inline half() { }

inline half(float f)
{
*this = makefast(f);
}

static half makeslow(float f);
static half makefast(float f);

static inline half makebits(uint16_t x)
{
half ret;
ret.m_bits = x;
return ret;
}

inline operator float() const
{
int s = m_bits & 0x8000u;
int e = m_bits & 0x7c00u;
int m = m_bits & 0x03ffu;

union { float f; uint32_t x; } u;
u.x = 0;
u.x |= s << 16;
u.x |= (-15 + (e >> 10) + 127) << 23;
u.x |= m << 13;

return u.f;
}

inline uint16_t bits()
{
return m_bits;
}
};

} /* namespace lol */

#endif // __LOL_HALF_H__


Loading…
Cancel
Save