refactor approx_{log2,pow2,powf}

- Move to SkJumper_vectors.h
    - Fold the -127 and +2.774485010.
    - approx_powf(F,F) instead of approx_powf(F,float) for consistency.
    - A little layout reformatting.

Change-Id: If9cb3d62a097cb6ecf89f157a1dde672c1516371
Reviewed-on: https://skia-review.googlesource.com/13865
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
Mike Klein 2017-04-19 14:33:58 -04:00 committed by Skia Commit-Bot
parent ecc364c426
commit da16434928
4 changed files with 1499 additions and 1671 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -671,30 +671,6 @@ STAGE(table_g) { g = table(g, ctx); }
STAGE(table_b) { b = table(b, ctx); }
STAGE(table_a) { a = table(a, ctx); }
// See http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.html.
SI F approx_log2(F x) {
// e is a fair approximation of log2(x) in its own right...
F e = cast(bit_cast<U32>(x)) * C(1.0f / (1<<23)) - 127.0_f;
// ... but using the mantissa to refine its error is _much_ better.
F m = bit_cast<F>((bit_cast<U32>(x) & 0x007fffff_i) | 0x3f000000_i);
return e
+ 2.774485010_f
- 1.498030302_f * m
- 1.725879990_f / (0.3520887068_f + m);
}
SI F approx_pow2(F x) {
F f = fract(x);
return bit_cast<F>(round(C(1.0f * (1<<23)),
x + 121.2740575_f
- 1.490129070_f * f
+ 27.72802330_f / (4.84252568_f - f)));
}
SI F approx_powf(F x, float g) {
return approx_pow2(approx_log2(x) * g);
}
SI F parametric(F v, const SkJumper_ParametricTransferFunction* ctx) {
F r = if_then_else(v <= ctx->D, mad(ctx->C, v, ctx->F)
, approx_powf(mad(ctx->A, v, ctx->B), ctx->G) + ctx->E);

View File

@ -628,4 +628,28 @@ SI U16 bswap(U16 x) {
SI F fract(F v) { return v - floor_(v); }
// See http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.html.
SI F approx_log2(F x) {
// e - 127 is a fair approximation of log2(x) in its own right...
F e = cast(bit_cast<U32>(x)) * C(1.0f / (1<<23));
// ... but using the mantissa to refine its error is _much_ better.
F m = bit_cast<F>((bit_cast<U32>(x) & 0x007fffff_i) | 0x3f000000_i);
return e
- 124.225514990_f
- 1.498030302_f * m
- 1.725879990_f / (0.3520887068_f + m);
}
SI F approx_pow2(F x) {
F f = fract(x);
return bit_cast<F>(round(C(1.0f * (1<<23)),
x + 121.274057500_f
- 1.490129070_f * f
+ 27.728023300_f / (4.84252568_f - f)));
}
SI F approx_powf(F x, F y) {
return approx_pow2(approx_log2(x) * y);
}
#endif//SkJumper_vectors_DEFINED