aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2012-05-18 14:39:41 -0600
committerBrian Paul <[email protected]>2012-05-19 08:28:57 -0600
commit699c1894eea6a42a747ebbc3974bf0abf3d1dd88 (patch)
treeac60a35e6c92598564df7134804ada1bf5d1a1fc /src/mesa
parent31d59c78f01925c199fd3a49a27718b0659bbaf4 (diff)
mesa: reimplement IROUND(), add F_TO_I()
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. Reviewed-by: José Fonseca <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/imports.h57
1 files changed, 36 insertions, 21 deletions
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index aa5eb3200af..c0b6ceceac6 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