<br><br><div class="gmail_quote">On Fri, May 18, 2012 at 11:28 AM, Brian Paul <span dir="ltr">&lt;<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 05/18/2012 10:11 AM, Jose Fonseca wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
----- Original Message -----<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
A while back I noticed that the piglit roundmode-pixelstore and<br>
roundmode-getinteger tests pass on my 64-bit Fedora system but fail<br>
on<br>
a 32-bit Ubuntu system.  Both glGetIntegerv() and glPixelStoref()<br>
  use<br>
the IROUND() function to convert floats to ints.<br>
<br>
The implementation if IROUND() that uses the x86 fistp instruction is<br>
protected with:<br>
<br></div>
#if defined(USE_X86_ASM)&amp;&amp;  defined(__GNUC__)&amp;&amp;  defined(__i386__)<div class="im"><br>
<br>
but that evaluates to 0 on x86-64 (neither USE_X86_ASM nor __i386__<br>
are defined) so we use the C fallback:<br>
<br>
#define IROUND(f)  ((int) (((f)&gt;= 0.0F) ? ((f) + 0.5F) : ((f) -<br>
0.5F)))<br>
<br>
The C version of IROUND() does what we want for the piglit tests but<br>
not the x86 version.  I think the default x86 rounding mode is<br>
FE_UPWARD so that explains the failures.<br>
<br>
<br>
So I think I&#39;d like to do the following:<br>
<br>
1. Enable the x86 fistp-based functions in imports.h for x86-64.<br>
</div></blockquote><div class="im">
<br>
It&#39;s illegal/inneficient to use x87 on x86-64. We should use the appropriate SSE intrisinsic instead.<br></div></blockquote></blockquote><div><br></div><div>The instruction is &quot;cvtss2si&quot;. Even if you use SSE here, you depend on the rounding mode in the MXCSR register, which means you&#39;ll have to set that, because some applications change this mode to use a faster or more precise rounding mode. It&#39;s the parallel problem that you have with &quot;fistp&quot;.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">

<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2. Rename IROUND() to IROUND_FAST() and define it as float-&gt;int<br>
conversion by whatever method is fastest.<br>
<br>
3. Define IROUND() as round to nearest int.  For the x86 fistp<br>
implementation this would involve setting/restoring the rounding<br>
mode.<br></blockquote></div></blockquote></blockquote><div><br></div><div>If I recall, it is generally run with some other rounding mode other than &quot;truncate&quot; by default, so usually float -&gt; int conversions that involve truncation (C cast) require changing the rounding mode <i>to truncation</i>. This was such a problem that in SSE3 there is &quot;fisttp&quot; which is &quot;FP integer store with truncation&quot;. I guess though if the default rounding mode causes problems, there isn&#39;t much that can be done but change it each time.</div>
<div><br></div><div>Patrick</div></div>