summaryrefslogtreecommitdiffstats
path: root/src/glsl/ir_optimization.h
diff options
context:
space:
mode:
authorIago Toral Quiroga <itoral@igalia.com>2015-01-20 17:09:59 +0100
committerIago Toral Quiroga <itoral@igalia.com>2015-02-03 13:19:36 +0100
commit5dfb085ff325df3dbefda515f06106469babbefc (patch)
treeacf8e618b2e412ca3846a98d96e9484841ae4496 /src/glsl/ir_optimization.h
parentc27d23f0c8e952d8ec340c4c9cd3ad026cd6187b (diff)
downloadexternal_mesa3d-5dfb085ff325df3dbefda515f06106469babbefc.zip
external_mesa3d-5dfb085ff325df3dbefda515f06106469babbefc.tar.gz
external_mesa3d-5dfb085ff325df3dbefda515f06106469babbefc.tar.bz2
glsl: Improve precision of mod(x,y)
Currently, Mesa uses the lowering pass MOD_TO_FRACT to implement mod(x,y) as y * fract(x/y). This implementation has a down side though: it introduces precision errors due to the fract() operation. Even worse, since the result of fract() is multiplied by y, the larger y gets the larger the precision error we produce, so for large enough numbers the precision loss is significant. Some examples on i965: Operation Precision error ----------------------------------------------------- mod(-1.951171875, 1.9980468750) 0.0000000447 mod(121.57, 13.29) 0.0000023842 mod(3769.12, 321.99) 0.0000762939 mod(3769.12, 1321.99) 0.0001220703 mod(-987654.125, 123456.984375) 0.0160663128 mod( 987654.125, 123456.984375) 0.0312500000 This patch replaces the current lowering pass with a different one (MOD_TO_FLOOR) that follows the recommended implementation in the GLSL man pages: mod(x,y) = x - y * floor(x/y) This implementation eliminates the precision errors at the expense of an additional add instruction on some systems. On systems that can do negate with multiply-add in a single operation this new implementation would come at no additional cost. v2 (Ian Romanick) - Do not clone operands because when they are expressions we would be duplicating them and that can lead to suboptimal code. Fixes the following 16 dEQP tests: dEQP-GLES3.functional.shaders.builtin_functions.precision.mod.mediump_* dEQP-GLES3.functional.shaders.builtin_functions.precision.mod.highp_* Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Diffstat (limited to 'src/glsl/ir_optimization.h')
-rw-r--r--src/glsl/ir_optimization.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 34e0b4b..912d910 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -34,7 +34,7 @@
#define EXP_TO_EXP2 0x04
#define POW_TO_EXP2 0x08
#define LOG_TO_LOG2 0x10
-#define MOD_TO_FRACT 0x20
+#define MOD_TO_FLOOR 0x20
#define INT_DIV_TO_MUL_RCP 0x40
#define BITFIELD_INSERT_TO_BFM_BFI 0x80
#define LDEXP_TO_ARITH 0x100