glsl: improve the accuracy of the asin() builtin function.
authorPaul Berry <stereotype441@gmail.com>
Wed, 27 Jul 2011 21:34:12 +0000 (14:34 -0700)
committerPaul Berry <stereotype441@gmail.com>
Mon, 1 Aug 2011 21:37:38 +0000 (14:37 -0700)
commitd4c80f5f85c749df3fc091ff07b60ef4989fa6d9
treeab95a4da310d6f2cb68c493115e139c2203969a3
parent5541920e0ac4ea8383c7f896daba24a304aafec6
glsl: improve the accuracy of the asin() builtin function.

The previous formula for asin(x) was algebraically equivalent to:

sign(x)*(pi/2 - sqrt(1-|x|)*(A + B|x| + C|x|^2))

where A, B, and C were arbitrary constants determined by a curve fit.

This formula had a worst case absolute error of 0.00448, an unbounded
worst case relative error, and a discontinuity near x=0.

Changed the formula to:

sign(x)*(pi/2 - sqrt(1-|x|)*(pi/2 + (pi/4-1)|x| + A|x|^2 + B|x|^3))

where A and B are arbitrary constants determined by a curve fit.  This
has a worst case absolute error of 0.00039, a worst case relative
error of 0.000405, and no discontinuities.

I don't expect a significant performance degradation, since the extra
multiply-accumulate should be fast compared to the sqrt() computation.

Fixes piglit tests {vs,fs}-asin-float and {vs,fs}-atan-*
src/glsl/builtins/ir/asin