474239c784
- Use 3x3 eigensolver for initial fit in ZOH. Slightly better perf and RMSE than power method. - Remove use of double precision in ZOH - speeds up by 12%. - Fixed RGBM encoding that was broken for HDR images. - Use gamma-2.0 space for RGBM for HDR images (improves precision in darks). - Use UNORM instead of TYPELESS formats when saving a DX10 .dds file. The TYPELESS formats break most viewers. - Cleaned up warnings in ZOH code. - Command-line utils will warn if you give them an unrecognized parameter. - Added VS2010 profiling results.
94 lines
2.3 KiB
C++
94 lines
2.3 KiB
C++
#pragma once
|
|
#ifndef NV_MATH_HALF_H
|
|
#define NV_MATH_HALF_H
|
|
|
|
#include "nvmath.h"
|
|
|
|
namespace nv {
|
|
|
|
uint32 half_to_float( uint16 h );
|
|
uint16 half_from_float( uint32 f );
|
|
|
|
// vin,vout must be 16 byte aligned. count must be a multiple of 8.
|
|
// implement a non-SSE version if we need it. For now, this naming makes it clear this is only available when SSE2 is
|
|
void half_to_float_array_SSE2(const uint16 * vin, float * vout, int count);
|
|
|
|
void half_init_tables();
|
|
|
|
extern uint32 mantissa_table[2048];
|
|
extern uint32 exponent_table[64];
|
|
extern uint32 offset_table[64];
|
|
|
|
// Fast half to float conversion based on:
|
|
// http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
|
inline uint32 fast_half_to_float(uint16 h)
|
|
{
|
|
// Initialize table if necessary.
|
|
if (mantissa_table[0] != 0)
|
|
half_init_tables();
|
|
uint exp = h >> 10;
|
|
return mantissa_table[offset_table[exp] + (h & 0x3ff)] + exponent_table[exp];
|
|
}
|
|
|
|
|
|
inline uint16 to_half(float c) {
|
|
union { float f; uint32 u; } f;
|
|
f.f = c;
|
|
return nv::half_from_float( f.u );
|
|
}
|
|
|
|
inline float to_float(uint16 c) {
|
|
union { float f; uint32 u; } f;
|
|
f.u = nv::fast_half_to_float( c );
|
|
return f.f;
|
|
}
|
|
|
|
|
|
union Half {
|
|
uint16 raw;
|
|
struct {
|
|
#if NV_BIG_ENDIAN
|
|
uint negative:1;
|
|
uint biasedexponent:5;
|
|
uint mantissa:10;
|
|
#else
|
|
uint mantissa:10;
|
|
uint biasedexponent:5;
|
|
uint negative:1;
|
|
#endif
|
|
} field;
|
|
};
|
|
|
|
|
|
inline float TestHalfPrecisionAwayFromZero(float input)
|
|
{
|
|
Half h;
|
|
h.raw = to_half(input);
|
|
h.raw += 1;
|
|
|
|
float f = to_float(h.raw);
|
|
|
|
// Subtract the initial value to find our precision
|
|
float delta = f - input;
|
|
|
|
return delta;
|
|
}
|
|
|
|
inline float TestHalfPrecisionTowardsZero(float input)
|
|
{
|
|
Half h;
|
|
h.raw = to_half(input);
|
|
h.raw -= 1;
|
|
|
|
float f = to_float(h.raw);
|
|
|
|
// Subtract the initial value to find our precision
|
|
float delta = f - input;
|
|
|
|
return -delta;
|
|
}
|
|
|
|
} // nv namespace
|
|
|
|
#endif // NV_MATH_HALF_H
|