[Mesa-dev] [PATCH] Fixed bug in unclamped float to ubyte conversion.
Stéphane Marchesin
stephane.marchesin at gmail.com
Fri May 10 14:12:50 PDT 2013
On Fri, May 10, 2013 at 12:57 PM, Manfred Ernst <ernstm at chromium.org> wrote:
> Problem: The IEEE float optimized version of UNCLAMPED_FLOAT_TO_UBYTE in macros.h
> computed incorrect results for inputs in the range 0x3f7f0000 (=0.99609375) to
> 0x3f7f7f80 (=0.99803924560546875) inclusive. 0x3f7f7f80 is the IEEE float
> value that results in 254.5 when multiplied by 255. With rounding mode
> "round to closest even integer", this is the largest float in the range 0.0-1.0
> that is converted to 254 by the generic implementation of
> UNCLAMPED_FLOAT_TO_UBYTE. The IEEE float optimized version incorrectly defined
> the cut-off for mapping to 255 as 0x3f7f0000 (=255.0/256.0). The same bug was
> present in the function float_to_ubyte in u_math.h.
>
> Fix: The proposed fix replaces the incorrect cut-off value by 0x3f800000, which
> is the IEEE float representation of 1.0f. 0x3f7f7f81 (or any value in between)
> would also work, but 1.0f is probably cleaner.
>
> The patch does not regress piglit on llvmpipe and on i965 on sandy bridge.
> Tested-by Stéphane Marchesin <marcheu at chromium.org>
> Reviewed-by Stéphane Marchesin <marcheu at chromium.org>
> ---
> src/gallium/auxiliary/util/u_math.h | 4 ++--
> src/mesa/main/macros.h | 4 ++--
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
> index 607fbec..7e57e61 100644
> --- a/src/gallium/auxiliary/util/u_math.h
> +++ b/src/gallium/auxiliary/util/u_math.h
> @@ -540,14 +540,14 @@ ubyte_to_float(ubyte ub)
> static INLINE ubyte
> float_to_ubyte(float f)
> {
> - const int ieee_0996 = 0x3f7f0000; /* 0.996 or so */
> + const int ieee_one = 0x3f800000; /* 1.0f */
> union fi tmp;
>
> tmp.f = f;
> if (tmp.i < 0) {
> return (ubyte) 0;
> }
> - else if (tmp.i >= ieee_0996) {
> + else if (tmp.i >= ieee_one) {
> return (ubyte) 255;
> }
> else {
> diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
> index ac24672..af10076 100644
> --- a/src/mesa/main/macros.h
> +++ b/src/mesa/main/macros.h
> @@ -142,7 +142,7 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
> *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255]
> ***/
> #if defined(USE_IEEE) && !defined(DEBUG)
> -#define IEEE_0996 0x3f7f0000 /* 0.996 or so */
> +#define IEEE_ONE 0x3f800000 /* 1.0F */
Please respin this using IEEE_ONE from compiler.h
Stéphane
> /* This function/macro is sensitive to precision. Test very carefully
> * if you change it!
> */
> @@ -152,7 +152,7 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
> __tmp.f = (F); \
> if (__tmp.i < 0) \
> UB = (GLubyte) 0; \
> - else if (__tmp.i >= IEEE_0996) \
> + else if (__tmp.i >= IEEE_ONE) \
> UB = (GLubyte) 255; \
> else { \
> __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F; \
> --
> 1.8.2.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list