Skip to content
  • Neil Roberts's avatar
    format_utils: Use a more precise conversion when decreasing bits · a4ab08bf
    Neil Roberts authored
    When converting to a format that has fewer bits the previous code was just
    shifting off the bits. This doesn't provide very accurate results. For example
    when converting from 8 bits to 5 bits it is equivalent to doing this:
    
    x * 32 / 256
    
    This works as if it's taking a value from a range where 256 represents 1.0 and
    scaling it down to a range where 32 represents 1.0. However this is not
    correct because it is actually 255 and 31 that represent 1.0.
    
    We can do better with a formula like this:
    
    (x * 31 + 127) / 255
    
    The +127 is to make it round correctly.
    
    The new code has a special case to use uint64_t when the result of the
    multiplication would overflow an unsigned int. This function is inline and
    only ever called with constant values so hopefully the if statements will be
    folded.
    
    The main incentive to do this is to make the CPU conversion path pick the same
    values as the hardware would if it did the conversion. This fixes failures
    with the ‘texsubimage pbo’ test when using the patches from here:
    
    http://lists.freedesktop.org/archives/mesa-dev/2015-January/074312.html
    
    
    
    v2: Use 64-bit arithmetic when src_bits+dst_bits > 32
    
    Reviewed-by: default avatarJason Ekstrand <jason.ekstrand@intel.com>
    a4ab08bf