glsl 1.30: Fix numerical instabilities in asinh
The formula we were previously using for asinh: asinh x = ln(x + sqrt(x * x + 1)) is numerically unstable: when x is a large negative value, the quantity x + sqrt(x * x + 1) is a small positive value (on the order of 1/(2|x|)). Since the logarithm function is very sensitive in this range, any error in the computation of the square root manifests as a large error in the result. This patch changes to the equivalent formula: asinh x = sign(x) * ln(abs(x) + sqrt(x * x + 1)) which is only slightly more expensive to compute, and is numerically stable for all x. Fixes piglit tests spec/glsl-1.30/execution/built-in-functions/[fv]s-asinh-*. Reviewed-by: Chad Versace <chad@chad-versace.us> Acked-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
b79782cbed
commit
9c75527299
|
@ -2,20 +2,52 @@
|
|||
(signature float
|
||||
(parameters
|
||||
(declare (in) float x))
|
||||
((return (expression float log (expression float + (var_ref x) (expression float sqrt (expression float + (expression float * (var_ref x) (var_ref x)) (constant float (1)))))))))
|
||||
((return (expression float *
|
||||
(expression float sign (var_ref x))
|
||||
(expression float log
|
||||
(expression float +
|
||||
(expression float abs (var_ref x))
|
||||
(expression float sqrt
|
||||
(expression float +
|
||||
(expression float * (var_ref x) (var_ref x))
|
||||
(constant float (1))))))))))
|
||||
|
||||
(signature vec2
|
||||
(parameters
|
||||
(declare (in) vec2 x))
|
||||
((return (expression vec2 log (expression vec2 + (var_ref x) (expression vec2 sqrt (expression vec2 + (expression vec2 * (var_ref x) (var_ref x)) (constant float (1)))))))))
|
||||
((return (expression vec2 *
|
||||
(expression vec2 sign (var_ref x))
|
||||
(expression vec2 log
|
||||
(expression vec2 +
|
||||
(expression vec2 abs (var_ref x))
|
||||
(expression vec2 sqrt
|
||||
(expression vec2 +
|
||||
(expression vec2 * (var_ref x) (var_ref x))
|
||||
(constant float (1))))))))))
|
||||
|
||||
(signature vec3
|
||||
(parameters
|
||||
(declare (in) vec3 x))
|
||||
((return (expression vec3 log (expression vec3 + (var_ref x) (expression vec3 sqrt (expression vec3 + (expression vec3 * (var_ref x) (var_ref x)) (constant float (1)))))))))
|
||||
((return (expression vec3 *
|
||||
(expression vec3 sign (var_ref x))
|
||||
(expression vec3 log
|
||||
(expression vec3 +
|
||||
(expression vec3 abs (var_ref x))
|
||||
(expression vec3 sqrt
|
||||
(expression vec3 +
|
||||
(expression vec3 * (var_ref x) (var_ref x))
|
||||
(constant float (1))))))))))
|
||||
|
||||
(signature vec4
|
||||
(parameters
|
||||
(declare (in) vec4 x))
|
||||
((return (expression vec4 log (expression vec4 + (var_ref x) (expression vec4 sqrt (expression vec4 + (expression vec4 * (var_ref x) (var_ref x)) (constant float (1)))))))))
|
||||
((return (expression vec4 *
|
||||
(expression vec4 sign (var_ref x))
|
||||
(expression vec4 log
|
||||
(expression vec4 +
|
||||
(expression vec4 abs (var_ref x))
|
||||
(expression vec4 sqrt
|
||||
(expression vec4 +
|
||||
(expression vec4 * (var_ref x) (var_ref x))
|
||||
(constant float (1))))))))))
|
||||
))
|
||||
|
|
Loading…
Reference in New Issue