exact divide by 255 with NEON
Change-Id: Ib121eb0d5af1f22f48f517fe909112a77d92032e Reviewed-on: https://skia-review.googlesource.com/113666 Commit-Queue: Mike Klein <mtklein@chromium.org> Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
parent
ba321b6017
commit
d8853ec0fd
@ -2487,6 +2487,11 @@ static void start_pipeline(const size_t x0, const size_t y0,
|
||||
SI U16 div255(U16 v) {
|
||||
#if 0
|
||||
return (v+127)/255; // The ideal rounding divide by 255.
|
||||
#elif 1 && defined(__ARM_NEON)
|
||||
// With NEON we can compute (v+127)/255 as (v + ((v+128)>>8) + 128)>>8
|
||||
// just as fast as we can do the approximation below, so might as well be correct!
|
||||
// First we compute v + ((v+128)>>8), then one more round of (...+128)>>8 to finish up.
|
||||
return vrshrq_n_u16(vrsraq_n_u16(v, v, 8), 8);
|
||||
#else
|
||||
return (v+255)/256; // A good approximation of (v+127)/255.
|
||||
#endif
|
||||
|
@ -750,3 +750,23 @@ DEF_TEST(DoubleSaturate32, reporter) {
|
||||
REPORTER_ASSERT(reporter, r.fExpectedInt == i);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__ARM_NEON)
|
||||
#include <arm_neon.h>
|
||||
|
||||
DEF_TEST(NeonU16Div255, r) {
|
||||
|
||||
for (int v = 0; v <= 255*255; v++) {
|
||||
int want = (v + 127)/255;
|
||||
|
||||
uint16x8_t V = vdupq_n_u16(v);
|
||||
int got = vrshrq_n_u16(vrsraq_n_u16(V, V, 8), 8)[0];
|
||||
|
||||
if (got != want) {
|
||||
SkDebugf("%d -> %d, want %d\n", v, got, want);
|
||||
}
|
||||
REPORTER_ASSERT(r, got == want);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user