[Mesa-dev] [PATCH] Fixed bug in unclamped float to ubyte conversion.

Brian Paul brianp at vmware.com
Wed Jun 12 07:42:34 PDT 2013


On 06/07/2013 05:20 PM, Stéphane Marchesin wrote:
> Ping, does anyone else want to review this patch?
>
> Stéphane
>
>
> On Fri, May 10, 2013 at 3:56 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 | 3 +--
>>   src/mesa/main/macros.h              | 3 +--
>>   2 files changed, 2 insertions(+), 4 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
>> index 607fbec..64d16cb 100644
>> --- a/src/gallium/auxiliary/util/u_math.h
>> +++ b/src/gallium/auxiliary/util/u_math.h
>> @@ -540,14 +540,13 @@ ubyte_to_float(ubyte ub)
>>   static INLINE ubyte
>>   float_to_ubyte(float f)
>>   {
>> -   const int ieee_0996 = 0x3f7f0000;   /* 0.996 or so */
>>      union fi tmp;
>>
>>      tmp.f = f;
>>      if (tmp.i < 0) {
>>         return (ubyte) 0;
>>      }
>> -   else if (tmp.i >= ieee_0996) {
>> +   else if (tmp.i >= 0x3f800000 /* 1.0f */) {
>>         return (ubyte) 255;
>>      }
>>      else {
>> diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
>> index ac24672..8f5b5ae 100644
>> --- a/src/mesa/main/macros.h
>> +++ b/src/mesa/main/macros.h
>> @@ -142,7 +142,6 @@ 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 */
>>   /* This function/macro is sensitive to precision.  Test very carefully
>>    * if you change it!
>>    */
>> @@ -152,7 +151,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
>>

Reviewed-by: Brian Paul <brianp at vmware.com>



More information about the mesa-dev mailing list