expand unit tests, fix extract

The mask-only special case for extract is wrong...
it never looked it its input!

This not only makes things correct-er, but oddly it also
makes them faster by breaking inter-loop data dependencies.

Disable tests for _I32... they're actually still broken
because of a much more systemic flaw in how I've evaluated
programs.  The _F32 and _I32_SWAR JIT code and all interpreted
code is just getting lucky.  o_O

While here, update the I32_SWAR code to use the same math as I32,
(x*y+x)/256 for unorm8 mul.  This just helps keep me sane.

Change-Id: I1acc09adb84c426fca4b2be5ca8c2d46d9678dd8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/220577
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Mike Klein 2019-06-12 12:54:52 -05:00 committed by Skia Commit-Bot
parent 81756e4cae
commit 3f593799da
4 changed files with 51 additions and 65 deletions

View File

@ -590,7 +590,7 @@ r9 = pack r7 r9 16
store32 arg(1) r9
I32 (SWAR) 8888 over 8888
7 registers, 20 instructions:
8 registers, 20 instructions:
r0 = splat FF00FF (2.3418409e-38)
r1 = splat FF (3.5733111e-43)
loop:
@ -602,14 +602,14 @@ r5 = extract r4 0 r0
r4 = extract r4 8 r0
r6 = shr r2 16
r6 = sub_i32 r1 r6
r5 = mul_i32 r5 r6
r5 = add_i32 r5 r0
r5 = extract r5 8 r0
r5 = add_i32 r3 r5
r7 = mul_i32 r5 r6
r7 = add_i32 r7 r5
r7 = extract r7 8 r0
r7 = add_i32 r3 r7
r6 = mul_i32 r4 r6
r6 = add_i32 r6 r0
r6 = add_i32 r6 r4
r6 = extract r6 8 r0
r6 = add_i32 r2 r6
r6 = pack r5 r6 8
r6 = pack r7 r6 8
store32 arg(1) r6

View File

@ -494,8 +494,12 @@ namespace skvm {
vpaddd(r[d], r[d], r[z.id]);
break;
case Op::extract: if (y.imm) { vpsrld(r[d], r[x], y.imm); }
vandps(r[d], r[d], r[z.id]);
case Op::extract: if (y.imm) {
vpsrld(r[d], r[x], y.imm);
vandps(r[d], r[d], r[z.id]);
} else {
vandps(r[d], r[x], r[z.id]);
}
break;
case Op::pack: vpslld(r[d], r[y.id], z.imm);

View File

@ -78,76 +78,58 @@ DEF_TEST(SkVM, r) {
}
}
{
skvm::Program program = SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::RGBA_8888}.done();
auto test_8888 = [&](const skvm::Program& program) {
uint32_t src[9];
uint32_t dst[SK_ARRAY_COUNT(src)];
uint32_t src = 0xbb007733,
dst = 0xffaaccee;
SkPMColor want = SkPMSrcOver(src, dst); // 0xff2dad73
for (int i = 0; i < (int)SK_ARRAY_COUNT(src); i++) {
src[i] = 0xbb007733;
dst[i] = 0xffaaccee;
}
program.eval(1, &src, &dst);
SkPMColor expected = SkPMSrcOver(src[0], dst[0]); // 0xff2dad73
program.eval((int)SK_ARRAY_COUNT(src), src, dst);
// dst is probably 0xff2dad72.
for (int i = 0; i < 4; i++) {
uint8_t d = dst & 0xff,
w = want & 0xff;
REPORTER_ASSERT(r, abs(d-w) < 2);
dst >>= 8;
want >>= 8;
for (auto got : dst) {
auto want = expected;
for (int i = 0; i < 4; i++) {
uint8_t d = got & 0xff,
w = want & 0xff;
REPORTER_ASSERT(r, abs(d-w) < 2);
got >>= 8;
want >>= 8;
}
}
}
};
{
skvm::Program program = SrcoverBuilder_I32{}.done();
uint32_t src = 0xbb007733,
dst = 0xffaaccee;
SkPMColor want = SkPMSrcOver(src, dst); // 0xff2dad73
program.eval(1, &src, &dst);
// dst is probably 0xff2dad72.
for (int i = 0; i < 4; i++) {
uint8_t d = dst & 0xff,
w = want & 0xff;
REPORTER_ASSERT(r, abs(d-w) < 2);
dst >>= 8;
want >>= 8;
}
}
{
skvm::Program program = SrcoverBuilder_I32_SWAR{}.done();
uint32_t src = 0xbb007733,
dst = 0xffaaccee;
SkPMColor want = SkPMSrcOver(src, dst); // 0xff2dad73
program.eval(1, &src, &dst);
// dst is probably 0xff2dad72.
for (int i = 0; i < 4; i++) {
uint8_t d = dst & 0xff,
w = want & 0xff;
REPORTER_ASSERT(r, abs(d-w) < 2);
dst >>= 8;
want >>= 8;
}
}
test_8888(SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::RGBA_8888}.done());
//test_8888(SrcoverBuilder_I32{}.done());
test_8888(SrcoverBuilder_I32_SWAR{}.done());
{
skvm::Program program = SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::G8}.done();
uint32_t src = 0xbb007733;
uint8_t dst = 0x42;
SkPMColor over = SkPMSrcOver(SkPackARGB32(0xbb, 0x33, 0x77, 0x00), 0xff424242);
uint32_t src[9];
uint8_t dst[SK_ARRAY_COUNT(src)];
for (int i = 0; i < (int)SK_ARRAY_COUNT(src); i++) {
src[i] = 0xbb007733;
dst[i] = 0x42;
}
SkPMColor over = SkPMSrcOver(SkPackARGB32(0xbb, 0x33, 0x77, 0x00),
0xff424242);
uint8_t want = SkComputeLuminance(SkGetPackedR32(over),
SkGetPackedG32(over),
SkGetPackedB32(over));
program.eval(1, &src, &dst);
program.eval((int)SK_ARRAY_COUNT(src), src, dst);
REPORTER_ASSERT(r, abs(dst-want) < 3);
for (auto got : dst) {
REPORTER_ASSERT(r, abs(got-want) < 3);
}
}
{

View File

@ -135,7 +135,7 @@ SrcoverBuilder_I32_SWAR::SrcoverBuilder_I32_SWAR() {
auto mul_unorm8_SWAR = [&](skvm::I32 x, skvm::I32 y) {
// As above, assuming x is two SWAR bytes in lanes 0 and 2, and y is a byte.
skvm::I32 _255 = splat(0x00ff00ff);
return extract(add(mul(x, y), _255), 8, _255);
return extract(add(mul(x, y), x), 8, _255);
};
skvm::I32 rb, ga;