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:
parent
81756e4cae
commit
3f593799da
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user