[Mesa-dev] [PATCH v3 06/44] spirv/glsl450: fix atan2(x, x) case

Samuel Iglesias Gonsálvez siglesias at igalia.com
Wed Feb 6 10:44:35 UTC 2019


If x < 0 -> atan2(x, x) = -3*pi/4.
If x > 0 -> atan2(x, x) = pi/4.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
---
 src/compiler/spirv/vtn_glsl450.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/compiler/spirv/vtn_glsl450.c b/src/compiler/spirv/vtn_glsl450.c
index 21a2464d5e7..a6d2c5fdd07 100644
--- a/src/compiler/spirv/vtn_glsl450.c
+++ b/src/compiler/spirv/vtn_glsl450.c
@@ -35,6 +35,7 @@
 #define M_PIf   ((float) M_PI)
 #define M_PI_2f ((float) M_PI_2)
 #define M_PI_4f ((float) M_PI_4)
+#define M_minus_3PI_4f ((float) -3*M_PI_4)
 
 static nir_ssa_def *
 build_mat2_det(nir_builder *b, nir_ssa_def *col[2])
@@ -381,12 +382,16 @@ build_atan2(nir_builder *b, nir_ssa_def *y, nir_ssa_def *x)
     * continuous along the whole positive y = 0 half-line, so it won't affect
     * the result significantly.
     */
-   nir_ssa_def *result = nir_bcsel(b, nir_flt(b, nir_fmin(b, y, rcp_scaled_t), zero),
+   nir_ssa_def *atan2 = nir_bcsel(b, nir_flt(b, nir_fmin(b, y, rcp_scaled_t), zero),
                                    nir_fneg(b, arc), arc);
    nir_ssa_def *is_xy_zero = nir_iand(b,
                                      nir_feq(b, x, zero),
                                      nir_feq(b, y, zero));
-   return nir_bcsel(b, is_xy_zero, zero, result);
+   nir_ssa_def *res_equal = nir_bcsel(b, nir_feq(b, x, y),
+                                      nir_bcsel(b, nir_flt(b, x, zero), nir_imm_floatN_t(b, M_minus_3PI_4f, bit_size), nir_imm_floatN_t(b, M_PI_4f, bit_size)),
+                                      atan2);
+   nir_ssa_def *res =  nir_bcsel(b, is_xy_zero, zero, res_equal);
+   return res;
 }
 
 static nir_ssa_def *
-- 
2.19.1



More information about the mesa-dev mailing list