[Mesa-dev] [PATCH v2] format_utils: Use a more precise conversion when decreasing bits

Jason Ekstrand jason at jlekstrand.net
Wed Jan 14 12:25:05 PST 2015


This looks fine to me.  We should probably also do this for snorm formats.
I don't care if that's part of this or in a separate patch.
--Jason

Reviewed-by: Jason Ekstrand <jason.ekstrand at intel.com>

On Wed, Jan 14, 2015 at 11:46 AM, Neil Roberts <neil at linux.intel.com> wrote:

> 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
> ---
>
> Ok, this time I've actually run it through Piglit before sending it.
> It doesn't cause any regressions at least on IvyBridge.
>
>  src/mesa/main/format_utils.h | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/src/mesa/main/format_utils.h b/src/mesa/main/format_utils.h
> index b588695..b49415c 100644
> --- a/src/mesa/main/format_utils.h
> +++ b/src/mesa/main/format_utils.h
> @@ -96,10 +96,19 @@ _mesa_half_to_unorm(uint16_t x, unsigned dst_bits)
>  static inline unsigned
>  _mesa_unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits)
>  {
> -   if (src_bits < dst_bits)
> +   if (src_bits < dst_bits) {
>        return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits);
> -   else
> -      return x >> (src_bits - dst_bits);
> +   } else {
> +      unsigned src_half = (1 << (src_bits - 1)) - 1;
> +
> +      if (src_bits + dst_bits > sizeof(x) * 8) {
> +         assert(src_bits + dst_bits <= sizeof(uint64_t) * 8);
> +         return (((uint64_t) x * MAX_UINT(dst_bits) + src_half) /
> +                 MAX_UINT(src_bits));
> +      } else {
> +         return (x * MAX_UINT(dst_bits) + src_half) / MAX_UINT(src_bits);
> +      }
> +   }
>  }
>
>  static inline unsigned
> --
> 1.9.3
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150114/9feb5ce2/attachment.html>


More information about the mesa-dev mailing list