GLdc/GL/util.c
2026-02-28 14:26:22 +00:00

79 lines
2.5 KiB
C

#include "private.h"
uint32_t _glPackNormal(const GLfloat* nxyz) {
uint8_t bx = (uint8_t)((nxyz[0] + 1) * 127.5);
uint8_t by = (uint8_t)((nxyz[1] + 1) * 127.5);
uint8_t bz = (uint8_t)((nxyz[2] + 1) * 127.5);
return (bx << 16) | (by << 8) | bz;
}
void _glUnpackNormal(uint32_t packed, float* nxyz) {
nxyz[0] = ((packed >> 16) & 0xFF) / 127.5 - 1;
nxyz[1] = ((packed >> 8) & 0xFF) / 127.5 - 1;
nxyz[2] = (packed & 0xFF) / 127.5 - 1;
}
half_float_t _glPackHalfFloat(float f) {
// From BSD licensed code here: https://forums.developer.nvidia.com/t/error-when-trying-to-use-half-fp16/39786/10
uint32_t ia = *((uint32_t*) &f);
uint16_t ir;
ir = (ia >> 16) & 0x8000;
if((ia & 0x7f800000) == 0x7f800000) {
if((ia & 0x7fffffff) == 0x7f800000) {
ir |= 0x7c00; /* infinity */
} else {
ir |= 0x7e00 | ((ia >> (24 - 11)) & 0x1ff); /* NaN, quietened */
}
} else if((ia & 0x7f800000) >= 0x33000000) {
int shift = (int)((ia >> 23) & 0xff) - 127;
if(shift > 15) {
ir |= 0x7c00; /* infinity */
} else {
ia = (ia & 0x007fffff) | 0x00800000; /* extract mantissa */
if(shift < -14) { /* denormal */
ir |= ia >> (-1 - shift);
ia = ia << (32 - (-1 - shift));
} else { /* normal */
ir |= ia >> (24 - 11);
ia = ia << (32 - (24 - 11));
ir = ir + ((14 + shift) << 10);
}
/* IEEE-754 round to nearest of even */
if((ia > 0x80000000) || ((ia == 0x80000000) && (ir & 1))) {
ir++;
}
}
}
return ir;
}
float _glUnpackHalfFloat(half_float_t h) {
uint32_t sign = (h & 0x8000) << 16;
uint32_t exponent = ((h >> 10) & 0x1F);
uint32_t mantissa = (h & 0x3FF);
if(exponent == 0) {
if(mantissa == 0) {
return *((float*)(&sign)); // Zero
} else {
// Subnormal
while((mantissa & 0x400) == 0) {
mantissa <<= 1;
exponent--;
}
exponent++;
mantissa &= ~0x400;
}
} else if(exponent == 31) {
uint32_t tmp = (sign | 0x7F800000 | (mantissa << 13));
return *((float*)(&tmp)); // Inf or NaN
}
exponent = exponent + (127 - 15);
mantissa = mantissa << 13;
uint32_t f_bits = sign | (exponent << 23) | mantissa;
return *((float*) (&f_bits));
}