From: Brian Paul Date: Fri, 18 May 2012 20:39:41 +0000 (-0600) Subject: mesa: reimplement IROUND(), add F_TO_I() X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=699c1894eea6a42a747ebbc3974bf0abf3d1dd88;p=mesa.git 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 --- 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