Mesa (master): nir/spirv/glsl450: Implement IEEE-compliant handling of atan2(=?UTF-8?Q?=C2=B1=E2=88=9E?=, =?UTF-8?Q?=20=C2=B1=E2=88=9E?=).

Francisco Jerez currojerez at kemper.freedesktop.org
Tue Jan 31 19:21:01 UTC 2017


Module: Mesa
Branch: master
Commit: 11e9ebbf15ecf49d7ef02c2ec6c2d9d3ff0f1b6e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=11e9ebbf15ecf49d7ef02c2ec6c2d9d3ff0f1b6e

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Mon Jan 23 23:36:46 2017 -0800

nir/spirv/glsl450: Implement IEEE-compliant handling of atan2(±∞, ±∞).

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
Reviewed-by: Juan A. Suarez Romero <jasuarez at igalia.com>

---

 src/compiler/spirv/vtn_glsl450.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/compiler/spirv/vtn_glsl450.c b/src/compiler/spirv/vtn_glsl450.c
index 8509f64..dd38cc9 100644
--- a/src/compiler/spirv/vtn_glsl450.c
+++ b/src/compiler/spirv/vtn_glsl450.c
@@ -339,12 +339,32 @@ build_atan2(nir_builder *b, nir_ssa_def *y, nir_ssa_def *x)
    nir_ssa_def *rcp_scaled_t = nir_frcp(b, nir_fmul(b, t, scale));
    nir_ssa_def *s_over_t = nir_fmul(b, nir_fmul(b, s, scale), rcp_scaled_t);
 
+   /* For |x| = |y| assume tan = 1 even if infinite (i.e. pretend momentarily
+    * that ∞/∞ = 1) in order to comply with the rather artificial rules
+    * inherited from IEEE 754-2008, namely:
+    *
+    *  "atan2(±∞, −∞) is ±3π/4
+    *   atan2(±∞, +∞) is ±π/4"
+    *
+    * Note that this is inconsistent with the rules for the neighborhood of
+    * zero that are based on iterated limits:
+    *
+    *  "atan2(±0, −0) is ±π
+    *   atan2(±0, +0) is ±0"
+    *
+    * but GLSL specifically allows implementations to deviate from IEEE rules
+    * at (0,0), so we take that license (i.e. pretend that 0/0 = 1 here as
+    * well).
+    */
+   nir_ssa_def *tan = nir_bcsel(b, nir_feq(b, nir_fabs(b, x), nir_fabs(b, y)),
+                                one, nir_fabs(b, s_over_t));
+
    /* Calculate the arctangent and fix up the result if we had flipped the
     * coordinate system.
     */
    nir_ssa_def *arc = nir_fadd(b, nir_fmul(b, nir_b2f(b, flip),
                                            nir_imm_float(b, M_PI_2f)),
-                               build_atan(b, nir_fabs(b, s_over_t)));
+                               build_atan(b, tan));
 
    /* Rather convoluted calculation of the sign of the result.  When x < 0 we
     * cannot use fsign because we need to be able to distinguish between




More information about the mesa-commit mailing list