On Thu, Dec 8, 2016 at 8:41 PM, Roland Scheidegger <srol...@vmware.com> wrote:
> I'm wondering, isn't that actually a problem of the test, that is it > can't actually expect reasonable results with such input values? > Since within the shader languages those functions which are composed of > multiple other functions are usually allowed to basically accumulate all > the errors of said functions. Though I agree that results outside [-1,1] > would be odd... > No, not really. tanh() is well defined on the entire real line and always stays inside the interval (-1, 1). The problem is just that floating-point arithmatic explodes once x gets large enough. However, long before that point, it's flattened out to +- 1 (Not mathematically, but as far as floating-point precision is concerned). > btw I'm wondering if some vendors wouldn't implement that with slightly > simplified formula, e.g. (e^2x - 1) / (e^2x + 1) (this is what nvidia > used for cg apparently according to docs, saving one of the > exponentials). Might be worse for accuracy though (and won't solve this > problem, though it would now only need a one-sided clamp). > I would be interested to know if that formula would pass the dEQP precision tests... It would be simpler. > Roland > > Am 09.12.2016 um 02:41 schrieb Haixia Shi: > > Clamp input scalar value to range [-10, +10] to avoid precision problems > > when the absolute value of input is too large. > > > > Fixes dEQP-GLES3.functional.shaders.builtin_functions.precision.tanh.* > test > > failures. > > > > v2: added more explanation in the comment. > > v3: fixed a typo in the comment. > > > > Signed-off-by: Haixia Shi <h...@chromium.org> > > Cc: Jason Ekstrand <ja...@jlekstrand.net>, > > Cc: Stéphane Marchesin <marc...@chromium.org>, > > Cc: Kenneth Graunke <kenn...@whitecape.org> > > > > Change-Id: I324c948b3323ff8107127c42934f14459e124b95 > > --- > > src/compiler/glsl/builtin_functions.cpp | 13 +++++++++++-- > > 1 file changed, 11 insertions(+), 2 deletions(-) > > > > diff --git a/src/compiler/glsl/builtin_functions.cpp > b/src/compiler/glsl/builtin_functions.cpp > > index 3e4bcbb..0bacffb 100644 > > --- a/src/compiler/glsl/builtin_functions.cpp > > +++ b/src/compiler/glsl/builtin_functions.cpp > > @@ -3563,9 +3563,18 @@ builtin_builder::_tanh(const glsl_type *type) > > ir_variable *x = in_var(type, "x"); > > MAKE_SIG(type, v130, 1, x); > > > > + /* > > + * Clamp x to [-10, +10] to avoid precision problems. > > + * When x > 10, e^(-x) is so small relative to e^x that it gets > flushed to > > + * zero in the computation e^x + e^(-x). The same happens in the > other > > + * direction when x < -10. > > + */ > > + ir_variable *t = body.make_temp(type, "tmp"); > > + body.emit(assign(t, min2(max2(x, imm(-10.0f)), imm(10.0f)))); > > + > > /* (e^x - e^(-x)) / (e^x + e^(-x)) */ > > - body.emit(ret(div(sub(exp(x), exp(neg(x))), > > - add(exp(x), exp(neg(x)))))); > > + body.emit(ret(div(sub(exp(t), exp(neg(t))), > > + add(exp(t), exp(neg(t)))))); > > > > return sig; > > } > > > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev