util: when packing depth values, round to nearest.
authorMatthew McClure <mcclurem@vmware.com>
Thu, 26 Sep 2013 23:57:26 +0000 (16:57 -0700)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 4 Oct 2013 09:55:51 +0000 (10:55 +0100)
This patch adds the lrint, lrintf, llrint, and llrintf rounding utility
functions. When packing unorm depth values, we will round to nearest.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/util/u_math.h
src/gallium/auxiliary/util/u_pack_color.h

index 702d4e9d403470d92904e2075355435e06e26d82..478a4aa4d1773056eae0959654292e67c15b4ff8 100644 (file)
@@ -162,7 +162,59 @@ float log2f(float f)
 #endif
 
 
+#if __STDC_VERSION__ < 199901L && !defined(__cplusplus)
+static INLINE long int
+lrint(double d)
+{
+   long int rounded = (long int)(d + 0.5);
+
+   if (d - floor(d) == 0.5) {
+      if (rounded % 2 != 0)
+         rounded += (d > 0) ? -1 : 1;
+   }
+
+   return rounded;
+}
+
+static INLINE long int
+lrintf(float f)
+{
+   long int rounded = (long int)(f + 0.5f);
+
+   if (f - floorf(f) == 0.5f) {
+      if (rounded % 2 != 0)
+         rounded += (f > 0) ? -1 : 1;
+   }
+
+   return rounded;
+}
 
+static INLINE long long int
+llrint(double d)
+{
+   long long int rounded = (long long int)(d + 0.5);
+
+   if (d - floor(d) == 0.5) {
+      if (rounded % 2 != 0)
+         rounded += (d > 0) ? -1 : 1;
+   }
+
+   return rounded;
+}
+
+static INLINE long long int
+llrintf(float f)
+{
+   long long int rounded = (long long int)(f + 0.5f);
+
+   if (f - floorf(f) == 0.5f) {
+      if (rounded % 2 != 0)
+         rounded += (f > 0) ? -1 : 1;
+   }
+
+   return rounded;
+}
+#endif /* C99 */
 
 #define POW2_TABLE_SIZE_LOG2 9
 #define POW2_TABLE_SIZE (1 << POW2_TABLE_SIZE_LOG2)
index 102ad60517f3782ce113416f2588f5c578433b8f..36252738d68227df7db9a6ce15f8f919d4d4fb53 100644 (file)
@@ -528,12 +528,12 @@ util_pack_z(enum pipe_format format, double z)
    case PIPE_FORMAT_Z16_UNORM:
       if (z == 1.0)
          return 0xffff;
-      return (uint32_t) (z * 0xffff);
+      return (uint32_t) lrint(z * 0xffff);
    case PIPE_FORMAT_Z32_UNORM:
       /* special-case to avoid overflow */
       if (z == 1.0)
          return 0xffffffff;
-      return (uint32_t) (z * 0xffffffff);
+      return (uint32_t) llrint(z * 0xffffffff);
    case PIPE_FORMAT_Z32_FLOAT:
       fui.f = (float)z;
       return fui.ui;
@@ -541,12 +541,12 @@ util_pack_z(enum pipe_format format, double z)
    case PIPE_FORMAT_Z24X8_UNORM:
       if (z == 1.0)
          return 0xffffff;
-      return (uint32_t) (z * 0xffffff);
+      return (uint32_t) lrint(z * 0xffffff);
    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    case PIPE_FORMAT_X8Z24_UNORM:
       if (z == 1.0)
          return 0xffffff00;
-      return ((uint32_t) (z * 0xffffff)) << 8;
+      return ((uint32_t) lrint(z * 0xffffff)) << 8;
    case PIPE_FORMAT_S8_UINT:
       /* this case can get it via util_pack_z_stencil() */
       return 0;