greatly improve float saturation
This commit is contained in:
parent
a37a8cafd9
commit
f0d8653d07
30
src/external/rlsw.h
vendored
30
src/external/rlsw.h
vendored
|
|
@ -736,23 +736,28 @@ static inline void sw_vec4_transform(float dst[4], const float v[4], const sw_ma
|
||||||
|
|
||||||
static inline float sw_saturate(float x)
|
static inline float sw_saturate(float x)
|
||||||
{
|
{
|
||||||
// After several comparisons, this saturation method
|
// Clamps a floating point value between 0.0 and 1.0
|
||||||
// seems to be the most optimized by GCC and Clang,
|
|
||||||
// and it does not produce any conditional branching.
|
|
||||||
|
|
||||||
// However, it is possible that a clamp could be
|
// This implementation uses IEEE 754 bit manipulation:
|
||||||
// more efficient on certain platforms.
|
// - Uses the sign bit to detect negative values
|
||||||
// Comparisons will need to be made.
|
// - Directly compares with binary representation of 1.0f to detect values > 1.0
|
||||||
|
|
||||||
// SEE: https://godbolt.org/z/5qYznK5zj
|
// Use union to access the bits of the float as an unsigned int
|
||||||
|
union { float f; uint32_t u; } v;
|
||||||
|
v.f = x;
|
||||||
|
|
||||||
// Saturation from below: max(0, x)
|
// Check sign bit (bit 31): if set, x is negative, return 0.0f
|
||||||
float y = 0.5f * (x + fabsf(x));
|
if (v.u & 0x80000000) return 0.0f;
|
||||||
|
|
||||||
// Saturation from above: min(1, y)
|
// Extract the unsigned magnitude (exponent + mantissa bits)
|
||||||
return y - 0.5f * ((y - 1.0f) + fabsf(y - 1.0f));
|
uint32_t expMantissa = v.u & 0x7FFFFFFF;
|
||||||
|
|
||||||
// return (x < 0.0f) ? 0.0f : ((x > 1.0f) ? 1.0f : x);
|
// If magnitude > binary representation of 1.0f (0x3F800000), return 1.0f
|
||||||
|
// This efficiently handles all values > 1.0f without additional computation
|
||||||
|
if (expMantissa > 0x3F800000) return 1.0f;
|
||||||
|
|
||||||
|
// Value is between 0.0f and 1.0f inclusive, return unchanged
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sw_clampi(int v, int min, int max)
|
static inline int sw_clampi(int v, int min, int max)
|
||||||
|
|
@ -1247,7 +1252,6 @@ int sw_get_pixel_bpp(sw_pixelformat_e format)
|
||||||
return bpp;
|
return bpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void sw_get_pixel_grayscale(float* color, const void* pixels, uint32_t offset)
|
static inline void sw_get_pixel_grayscale(float* color, const void* pixels, uint32_t offset)
|
||||||
{
|
{
|
||||||
float gray = (float)((uint8_t*)pixels)[offset] * (1.0f / 255);
|
float gray = (float)((uint8_t*)pixels)[offset] * (1.0f / 255);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user