aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2015-06-25 16:47:52 -0700
committerMatt Turner <[email protected]>2015-08-03 09:24:51 -0700
commit594fc0f85953d11c455e7ab549308a773b312d70 (patch)
treef23cb5f74f95e7f97fcc8e5c01b166c9a90edde9
parentf55c408067a3ea3529fcf7cbbaa1a041a4a8849d (diff)
mesa: Replace F_TO_I() with _mesa_lroundevenf().
I'm not sure what the true meaning of "The rounding mode may vary." is, but it is the case that the IROUND() path rounds differently than the other paths (and does it wrong, at that). Like _mesa_roundeven{f,}(), just add an use _mesa_lroundeven{f,}() that has known semantics. Reviewed-by: Roland Scheidegger <[email protected]>
-rw-r--r--src/mesa/main/format_utils.h5
-rw-r--r--src/mesa/main/imports.h28
-rw-r--r--src/mesa/main/macros.h11
-rw-r--r--src/mesa/main/pack.c4
-rw-r--r--src/mesa/main/pixeltransfer.c11
-rw-r--r--src/util/rounding.h25
6 files changed, 42 insertions, 42 deletions
diff --git a/src/mesa/main/format_utils.h b/src/mesa/main/format_utils.h
index 7f500ec78da..00ec7774dd2 100644
--- a/src/mesa/main/format_utils.h
+++ b/src/mesa/main/format_utils.h
@@ -33,6 +33,7 @@
#include "imports.h"
#include "macros.h"
+#include "util/rounding.h"
extern const mesa_array_format RGBA32_FLOAT;
extern const mesa_array_format RGBA8_UBYTE;
@@ -84,7 +85,7 @@ _mesa_float_to_unorm(float x, unsigned dst_bits)
else if (x > 1.0f)
return MAX_UINT(dst_bits);
else
- return F_TO_I(x * MAX_UINT(dst_bits));
+ return _mesa_lroundevenf(x * MAX_UINT(dst_bits));
}
static inline unsigned
@@ -128,7 +129,7 @@ _mesa_float_to_snorm(float x, unsigned dst_bits)
else if (x > 1.0f)
return MAX_INT(dst_bits);
else
- return F_TO_I(x * MAX_INT(dst_bits));
+ return _mesa_lroundevenf(x * MAX_INT(dst_bits));
}
static inline int
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 9ffe3decd0f..d61279ac4e5 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -170,34 +170,6 @@ static inline int IROUND_POS(float f)
return (int) (f + 0.5F);
}
-#ifdef __x86_64__
-# include <xmmintrin.h>
-#endif
-
-/**
- * Convert float to int using a fast method. The rounding mode may vary.
- */
-static inline int F_TO_I(float f)
-{
-#if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
- int r;
- __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
- return r;
-#elif defined(USE_X86_ASM) && defined(_MSC_VER)
- int r;
- _asm {
- fld f
- fistp r
- }
- return r;
-#elif defined(__x86_64__)
- return _mm_cvt_ss2si(_mm_load_ss(&f));
-#else
- return IROUND(f);
-#endif
-}
-
-
/** Return (as an integer) floor of float */
static inline int IFLOOR(float f)
{
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index 07919a6e1e4..54df50c9cfe 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -33,6 +33,7 @@
#include "util/macros.h"
#include "util/u_math.h"
+#include "util/rounding.h"
#include "imports.h"
@@ -131,12 +132,12 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
#define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15)))
#define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16)))
#define UNCLAMPED_FLOAT_TO_USHORT(us, f) \
- us = ( (GLushort) F_TO_I( CLAMP((f), 0.0F, 1.0F) * 65535.0F) )
+ us = ( (GLushort) _mesa_lroundevenf( CLAMP((f), 0.0F, 1.0F) * 65535.0F) )
#define CLAMPED_FLOAT_TO_USHORT(us, f) \
- us = ( (GLushort) F_TO_I( (f) * 65535.0F) )
+ us = ( (GLushort) _mesa_lroundevenf( (f) * 65535.0F) )
#define UNCLAMPED_FLOAT_TO_SHORT(s, f) \
- s = ( (GLshort) F_TO_I( CLAMP((f), -1.0F, 1.0F) * 32767.0F) )
+ s = ( (GLshort) _mesa_lroundevenf( CLAMP((f), -1.0F, 1.0F) * 32767.0F) )
/***
*** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255]
@@ -167,9 +168,9 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
} while (0)
#else
#define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
- ub = ((GLubyte) F_TO_I(CLAMP((f), 0.0F, 1.0F) * 255.0F))
+ ub = ((GLubyte) _mesa_lroundevenf(CLAMP((f), 0.0F, 1.0F) * 255.0F))
#define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
- ub = ((GLubyte) F_TO_I((f) * 255.0F))
+ ub = ((GLubyte) _mesa_lroundevenf((f) * 255.0F))
#endif
static fi_type UINT_AS_UNION(GLuint u)
diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
index fb642b85be8..7147fd6e4fe 100644
--- a/src/mesa/main/pack.c
+++ b/src/mesa/main/pack.c
@@ -470,7 +470,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[],
static inline GLuint
clamp_float_to_uint(GLfloat f)
{
- return f < 0.0F ? 0 : F_TO_I(f);
+ return f < 0.0F ? 0 : _mesa_lroundevenf(f);
}
@@ -478,7 +478,7 @@ static inline GLuint
clamp_half_to_uint(GLhalfARB h)
{
GLfloat f = _mesa_half_to_float(h);
- return f < 0.0F ? 0 : F_TO_I(f);
+ return f < 0.0F ? 0 : _mesa_lroundevenf(f);
}
diff --git a/src/mesa/main/pixeltransfer.c b/src/mesa/main/pixeltransfer.c
index 51f2ebf768f..22eac00a7df 100644
--- a/src/mesa/main/pixeltransfer.c
+++ b/src/mesa/main/pixeltransfer.c
@@ -35,6 +35,7 @@
#include "pixeltransfer.h"
#include "imports.h"
#include "mtypes.h"
+#include "util/rounding.h"
/*
@@ -94,10 +95,10 @@ _mesa_map_rgba( const struct gl_context *ctx, GLuint n, GLfloat rgba[][4] )
GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
- rgba[i][RCOMP] = rMap[F_TO_I(r * rscale)];
- rgba[i][GCOMP] = gMap[F_TO_I(g * gscale)];
- rgba[i][BCOMP] = bMap[F_TO_I(b * bscale)];
- rgba[i][ACOMP] = aMap[F_TO_I(a * ascale)];
+ rgba[i][RCOMP] = rMap[(int)_mesa_lroundevenf(r * rscale)];
+ rgba[i][GCOMP] = gMap[(int)_mesa_lroundevenf(g * gscale)];
+ rgba[i][BCOMP] = bMap[(int)_mesa_lroundevenf(b * bscale)];
+ rgba[i][ACOMP] = aMap[(int)_mesa_lroundevenf(a * ascale)];
}
}
@@ -236,7 +237,7 @@ _mesa_apply_ci_transfer_ops(const struct gl_context *ctx,
GLuint i;
for (i = 0; i < n; i++) {
const GLuint j = indexes[i] & mask;
- indexes[i] = F_TO_I(ctx->PixelMaps.ItoI.Map[j]);
+ indexes[i] = _mesa_lroundevenf(ctx->PixelMaps.ItoI.Map[j]);
}
}
}
diff --git a/src/util/rounding.h b/src/util/rounding.h
index 0cbe9269f7b..088cf86dd08 100644
--- a/src/util/rounding.h
+++ b/src/util/rounding.h
@@ -21,6 +21,9 @@
* IN THE SOFTWARE.
*/
+#ifndef _ROUNDING_H
+#define _ROUNDING_H
+
#include <math.h>
#ifdef __SSE4_1__
@@ -76,3 +79,25 @@ _mesa_roundeven(double x)
return rint(x);
#endif
}
+
+/**
+ * \brief Rounds \c x to the nearest integer, with ties to the even integer,
+ * and returns the value as a long int.
+ */
+static inline long
+_mesa_lroundevenf(float x)
+{
+ return lrintf(x);
+}
+
+/**
+ * \brief Rounds \c x to the nearest integer, with ties to the even integer,
+ * and returns the value as a long int.
+ */
+static inline long
+_mesa_lroundeven(double x)
+{
+ return lrint(x);
+}
+
+#endif