On 07/02/2012 04:00 PM, Brian Paul wrote:
Won't this cause a constant and a non-constant to generate a different
value? The implementation of round() used in constant folding really
needs to be the same as the one used by the code generator. Right?
---
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:
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev