From: Paul Berry Date: Wed, 27 Jul 2011 21:34:12 +0000 (-0700) Subject: glsl: improve the accuracy of the asin() builtin function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d4c80f5f85c749df3fc091ff07b60ef4989fa6d9;p=mesa.git 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-* --- diff --git a/src/glsl/builtins/ir/asin b/src/glsl/builtins/ir/asin index e230ad614ee..45d9e672958 100644 --- a/src/glsl/builtins/ir/asin +++ b/src/glsl/builtins/ir/asin @@ -5,23 +5,26 @@ ((return (expression float * (expression float sign (var_ref x)) (expression float - - (expression float * - (constant float (3.1415926)) - (constant float (0.5))) + (constant float (1.5707964)) (expression float * (expression float sqrt (expression float - (constant float (1.0)) (expression float abs (var_ref x)))) (expression float + - (constant float (1.5707288)) + (constant float (1.5707964)) (expression float * (expression float abs (var_ref x)) (expression float + - (constant float (-0.2121144)) + (constant float (-0.21460183)) (expression float * - (constant float (0.0742610)) - (expression float abs (var_ref x)))))))))))) + (expression float abs (var_ref x)) + (expression float + + (constant float (0.086566724)) + (expression float * + (expression float abs (var_ref x)) + (constant float (-0.03102955)) + )))))))))))) (signature vec2 (parameters @@ -29,23 +32,26 @@ ((return (expression vec2 * (expression vec2 sign (var_ref x)) (expression vec2 - - (expression float * - (constant float (3.1415926)) - (constant float (0.5))) + (constant float (1.5707964)) (expression vec2 * (expression vec2 sqrt (expression vec2 - (constant float (1.0)) (expression vec2 abs (var_ref x)))) (expression vec2 + - (constant float (1.5707288)) + (constant float (1.5707964)) (expression vec2 * (expression vec2 abs (var_ref x)) (expression vec2 + - (constant float (-0.2121144)) + (constant float (-0.21460183)) (expression vec2 * - (constant float (0.0742610)) - (expression vec2 abs (var_ref x)))))))))))) + (expression vec2 abs (var_ref x)) + (expression vec2 + + (constant float (0.086566724)) + (expression vec2 * + (expression vec2 abs (var_ref x)) + (constant float (-0.03102955)) + )))))))))))) (signature vec3 (parameters @@ -53,23 +59,26 @@ ((return (expression vec3 * (expression vec3 sign (var_ref x)) (expression vec3 - - (expression float * - (constant float (3.1415926)) - (constant float (0.5))) + (constant float (1.5707964)) (expression vec3 * (expression vec3 sqrt (expression vec3 - (constant float (1.0)) (expression vec3 abs (var_ref x)))) (expression vec3 + - (constant float (1.5707288)) + (constant float (1.5707964)) (expression vec3 * (expression vec3 abs (var_ref x)) (expression vec3 + - (constant float (-0.2121144)) + (constant float (-0.21460183)) (expression vec3 * - (constant float (0.0742610)) - (expression vec3 abs (var_ref x)))))))))))) + (expression vec3 abs (var_ref x)) + (expression vec3 + + (constant float (0.086566724)) + (expression vec3 * + (expression vec3 abs (var_ref x)) + (constant float (-0.03102955)) + )))))))))))) (signature vec4 (parameters @@ -77,21 +86,24 @@ ((return (expression vec4 * (expression vec4 sign (var_ref x)) (expression vec4 - - (expression float * - (constant float (3.1415926)) - (constant float (0.5))) + (constant float (1.5707964)) (expression vec4 * (expression vec4 sqrt (expression vec4 - (constant float (1.0)) (expression vec4 abs (var_ref x)))) (expression vec4 + - (constant float (1.5707288)) + (constant float (1.5707964)) (expression vec4 * (expression vec4 abs (var_ref x)) (expression vec4 + - (constant float (-0.2121144)) + (constant float (-0.21460183)) (expression vec4 * - (constant float (0.0742610)) - (expression vec4 abs (var_ref x)))))))))))) + (expression vec4 abs (var_ref x)) + (expression vec4 + + (constant float (0.086566724)) + (expression vec4 * + (expression vec4 abs (var_ref x)) + (constant float (-0.03102955)) + )))))))))))) ))