nir/spirv/glsl450: Implement Asin and Acos.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 19 Jan 2016 20:15:36 +0000 (12:15 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 20 Jan 2016 00:14:05 +0000 (16:14 -0800)
src/glsl/nir/spirv/vtn_glsl450.c

index 82cfc8c91a9a9b163b0aebd5203c7a6813ef6b5c..b840e093dd501dceeae92c0fcfd930e8ae113506 100644 (file)
 #include "vtn_private.h"
 #include "GLSL.std.450.h"
 
+#define M_PIf   ((float) M_PI)
+#define M_PI_2f ((float) M_PI_2)
+#define M_PI_4f ((float) M_PI_4)
+
 static nir_ssa_def *
 build_mat2_det(nir_builder *b, nir_ssa_def *col[2])
 {
@@ -201,6 +205,22 @@ build_log(nir_builder *b, nir_ssa_def *x)
    return nir_fmul(b, nir_flog2(b, x), nir_imm_float(b, 1.0 / M_LOG2E));
 }
 
+static nir_ssa_def *
+build_asin(nir_builder *b, nir_ssa_def *x)
+{
+   nir_ssa_def *abs_x = nir_fabs(b, x);
+   return nir_fmul(b, nir_fsign(b, x),
+                   nir_fsub(b, nir_imm_float(b, M_PI_2f),
+                            nir_fmul(b, nir_fsqrt(b, nir_fsub(b, nir_imm_float(b, 1.0f), abs_x)),
+                                     nir_fadd(b, nir_imm_float(b, M_PI_2f),
+                                              nir_fmul(b, abs_x,
+                                                       nir_fadd(b, nir_imm_float(b, M_PI_4f - 1.0f),
+                                                                nir_fmul(b, abs_x,
+                                                                         nir_fadd(b, nir_imm_float(b, 0.086566724f),
+                                                                                  nir_fmul(b, abs_x,
+                                                                                           nir_imm_float(b, -0.03102955f))))))))));
+}
+
 static void
 handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
                    const uint32_t *w, unsigned count)
@@ -417,7 +437,14 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
    case GLSLstd450FindUMsb:   op = nir_op_ufind_msb;  break;
 
    case GLSLstd450Asin:
+      val->ssa->def = build_asin(nb, src[0]);
+      return;
+
    case GLSLstd450Acos:
+      val->ssa->def = nir_fsub(nb, nir_imm_float(nb, M_PI_2f),
+                                   build_asin(nb, src[0]));
+      return;
+
    case GLSLstd450Atan:
    case GLSLstd450Atan2:
    case GLSLstd450ModfStruct: