summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-01-27 16:58:42 -0800
committerKristian Høgsberg Kristensen <[email protected]>2016-01-27 19:55:21 -0800
commit7fb35a82281c2d245c7ae421893ffa287405b975 (patch)
tree04c31ffb944a01b0fb8db2e4fd137a79b94a27ec /src/glsl
parent983db2b8042ee8ca25a3870767e0d76940011034 (diff)
An alternate arccosine implementation
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/nir/spirv/vtn_glsl450.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/glsl/nir/spirv/vtn_glsl450.c b/src/glsl/nir/spirv/vtn_glsl450.c
index 219a9c7dc5f..01d72a1531e 100644
--- a/src/glsl/nir/spirv/vtn_glsl450.c
+++ b/src/glsl/nir/spirv/vtn_glsl450.c
@@ -208,6 +208,9 @@ build_log(nir_builder *b, nir_ssa_def *x)
static nir_ssa_def *
build_asin(nir_builder *b, nir_ssa_def *x)
{
+ /*
+ * asin(x) = sign(x) * (pi/2 - sqrt(1 - |x|) * (pi / 4 - 1 + |x| * (0.086566724 + |x| * -0.03102955)))
+ */
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),
@@ -221,6 +224,26 @@ build_asin(nir_builder *b, nir_ssa_def *x)
nir_imm_float(b, -0.03102955f))))))))));
}
+static nir_ssa_def *
+build_acos(nir_builder *b, nir_ssa_def *x)
+{
+ /*
+ * acos(x) = sign(x) * sqrt(1 - |x|) * (pi / 4 - 1 + |x| * (0.086566724 + |x| * -0.03102955))
+ */
+ nir_ssa_def *abs_x = nir_fabs(b, x);
+ nir_ssa_def *poly = 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))))))));
+ return nir_bcsel(b, nir_flt(b, x, nir_imm_float(b, 0)),
+ nir_fsub(b, nir_imm_float(b, M_PI), poly),
+ poly);
+}
+
/**
* Compute xs[0] + xs[1] + xs[2] + ... using fadd.
*/
@@ -583,8 +606,7 @@ handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
return;
case GLSLstd450Acos:
- val->ssa->def = nir_fsub(nb, nir_imm_float(nb, M_PI_2f),
- build_asin(nb, src[0]));
+ val->ssa->def = build_acos(nb, src[0]);
return;
case GLSLstd450Atan: