[Mesa-dev] [PATCH 2/2] util: Make CLAMP turn NaN into MIN.

Marek Olšák maraeo at gmail.com
Fri Jul 14 13:01:51 UTC 2017


Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Jul 14, 2017 6:38 AM, "Kenneth Graunke" <kenneth at whitecape.org> wrote:

> The previous implementation of CLAMP() allowed NaN to pass through
> unscathed, by failing both comparisons.  NaN isn't exactly a value
> between MIN and MAX, which can break the assumptions of many callers.
>
> This patch changes CLAMP to convert NaN to MIN, arbitrarily.  Callers
> that need NaN to be handled in a specific manner should probably open
> code something, or use a macro specifically designed to do that.
>
> Section 2.3.4.1 of the OpenGL 4.5 spec says:
>
>    "Any representable floating-point value is legal as input to a GL
>     command that requires floating-point data. The result of providing a
>     value that is not a floating-point number to such a command is
>     unspecified, but must not lead to GL interruption or termination.
>     In IEEE arithmetic, for example, providing a negative zero or a
>     denormalized number to a GL command yields predictable results,
>     while providing a NaN or an infinity yields unspecified results."
>
> While CLAMP may apply to more than just GL inputs, it seems reasonable
> to follow those rules, and allow MIN as an "unspecified result".
>
> This prevents assertion failures in i965 when running the games
> "XCOM: Enemy Unknown" and "XCOM: Enemy Within", which call
>
>    glTexEnv(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT,
>             -nan(0x7ffff3));
>
> presumably unintentionally.  i965 clamps the LOD bias to be in range,
> and asserts that it's in the proper range when converting to fixed
> point.  NaN is not, so it crashed.  We'd like to at least avoid that.
>
> Cc: Marek Olšák <maraeo at gmail.com>
> Cc: Roland Scheidegger <sroland at vmware.com>
> Cc: Ian Romanick <idr at freedesktop.org>
> ---
>  src/gallium/auxiliary/util/u_math.h | 3 ++-
>  src/util/macros.h                   | 4 ++--
>  2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_math.h
> b/src/gallium/auxiliary/util/u_math.h
> index 2ab5f03a662..a441b5457b2 100644
> --- a/src/gallium/auxiliary/util/u_math.h
> +++ b/src/gallium/auxiliary/util/u_math.h
> @@ -605,8 +605,9 @@ util_memcpy_cpu_to_le32(void * restrict dest, const
> void * restrict src, size_t
>  /**
>   * Clamp X to [MIN, MAX].
>   * This is a macro to allow float, int, uint, etc. types.
> + * We arbitrarily turn NaN into MIN.
>   */
> -#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) :
> (X)) )
> +#define CLAMP( X, MIN, MAX )  ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) :
> (MIN) )
>
>  #define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
>  #define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
> diff --git a/src/util/macros.h b/src/util/macros.h
> index a10f1de8145..a66f1bfed07 100644
> --- a/src/util/macros.h
> +++ b/src/util/macros.h
> @@ -244,8 +244,8 @@ do {                       \
>  /** Compute ceiling of integer quotient of A divided by B. */
>  #define DIV_ROUND_UP( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
>
> -/** Clamp X to [MIN,MAX] */
> -#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) :
> (X)) )
> +/** Clamp X to [MIN,MAX].  Turn NaN into MIN, arbitrarily. */
> +#define CLAMP( X, MIN, MAX )  ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) :
> (MIN) )
>
>  /** Minimum of two values: */
>  #define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
> --
> 2.13.3
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170714/979c830e/attachment-0001.html>


More information about the mesa-dev mailing list