[Mesa-dev] [PATCH 3/3] tgsi: implement ROUND and ROUNDEVEN instructions in exec module

Brian Paul brianp at vmware.com
Mon Jul 2 16:00:00 PDT 2012


---
 src/gallium/auxiliary/tgsi/tgsi_exec.c |   29 ++++++++++++++++++++++++-----
 1 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 4c5e9d1..c4413e7 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -320,10 +320,28 @@ static void
 micro_rnd(union tgsi_exec_channel *dst,
           const union tgsi_exec_channel *src)
 {
-   dst->f[0] = floorf(src->f[0] + 0.5f);
-   dst->f[1] = floorf(src->f[1] + 0.5f);
-   dst->f[2] = floorf(src->f[2] + 0.5f);
-   dst->f[3] = floorf(src->f[3] + 0.5f);
+   dst->f[0] = roundf(src->f[0]);
+   dst->f[1] = roundf(src->f[1]);
+   dst->f[2] = roundf(src->f[2]);
+   dst->f[3] = roundf(src->f[3]);
+}
+
+static void
+micro_rnde(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   /* GLSL spec:
+    * [roundEven] Returns a value equal to the nearest integer to x.
+    * A fractional part of 0.5 will round toward the nearest even integer.
+    * (Both 3.5 and 4.5 for x will return 4.0.)
+    */
+   unsigned i;
+   for (i = 0; i < 4; i++) {
+      float x = src->f[i];
+      /* if x is odd, half = 0.5, else half = 0.49999 */
+      float half = (((int) x) & 1) ? 0.5f : 0.499999f;
+      dst->f[i] = (x >= 0.0f) ? floorf(x + half) : ceilf(x - half);
+   }
 }
 
 static void
@@ -3550,8 +3568,9 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_ROUND:
-   case TGSI_OPCODE_ROUNDEVEN:
       exec_vector_unary(mach, inst, micro_rnd, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
+   case TGSI_OPCODE_ROUNDEVEN:
+      exec_vector_unary(mach, inst, micro_rnde, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_EX2:
-- 
1.7.3.4



More information about the mesa-dev mailing list