[Mesa-dev] [PATCH 1/2] mesa: reimplement IROUND(), add F_TO_I()

Brian Paul brianp at vmware.com
Fri May 18 14:10:15 PDT 2012


The different implementations of IROUND() behaved differently and in
the case of fistp, depended on the current x86 FPU rounding mode.
This caused some tests like piglit roundmode-pixelstore and
roundmode-getintegerv to fail on 32-bit x86 but pass on 64-bit x86.

Now IROUND() always rounds to the nearest integer (away from zero).
The new F_TO_I function converts a float to an int by whatever means
is fastest.  We'll use this where we're more concerned with performance
and not too worried to how the conversion is done.
---
 src/mesa/main/imports.h |   57 +++++++++++++++++++++++++++++-----------------
 1 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index aa5eb32..c0b6cec 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -285,19 +285,47 @@ static inline int GET_FLOAT_BITS( float x )
 #endif
 
 
-/***
- *** IROUND: return (as an integer) float rounded to nearest integer
- ***/
+/**
+ * Convert float to int by rounding to nearest integer, away from zero.
+ */
+static inline int IROUND(float f)
+{
+   return (int) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F));
+}
+
+
+/**
+ * Convert float to int64 by rounding to nearest integer.
+ */
+static inline GLint64 IROUND64(float f)
+{
+   return (GLint64) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F));
+}
+
+
+/**
+ * Convert positive float to int by rounding to nearest integer.
+ */
+static inline int IROUND_POS(float f)
+{
+   assert(f >= 0.0F);
+   return (int) (f + 0.5F);
+}
+
+
+/**
+ * Convert float to int using a fast method.  The rounding mode may vary.
+ * XXX We could use an x86-64/SSE2 version here.
+ */
 #if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__)
-static inline int iround(float f)
+static inline int F_TO_I(float f)
 {
    int r;
    __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
    return r;
 }
-#define IROUND(x)  iround(x)
 #elif defined(USE_X86_ASM) && defined(_MSC_VER)
-static inline int iround(float f)
+static inline int F_TO_I(float f)
 {
    int r;
    _asm {
@@ -306,9 +334,8 @@ static inline int iround(float f)
 	}
    return r;
 }
-#define IROUND(x)  iround(x)
 #elif defined(__WATCOMC__) && defined(__386__)
-long iround(float f);
+long F_TO_I(float f);
 #pragma aux iround =                    \
 	"push   eax"                        \
 	"fistp  dword ptr [esp]"            \
@@ -316,20 +343,8 @@ long iround(float f);
 	parm [8087]                         \
 	value [eax]                         \
 	modify exact [eax];
-#define IROUND(x)  iround(x)
-#else
-#define IROUND(f)  ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
-#endif
-
-#define IROUND64(f)  ((GLint64) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
-
-/***
- *** IROUND_POS: return (as an integer) positive float rounded to nearest int
- ***/
-#ifdef DEBUG
-#define IROUND_POS(f) (assert((f) >= 0.0F), IROUND(f))
 #else
-#define IROUND_POS(f) (IROUND(f))
+#define F_TO_I(f)  IROUND(f)
 #endif
 
 
-- 
1.7.3.4



More information about the mesa-dev mailing list