| Index: tests/Float16Test.cpp
|
| diff --git a/tests/Float16Test.cpp b/tests/Float16Test.cpp
|
| index 8ab56048e9fac2cfc98a046c2575e92727d308a9..3e057587c9243b4f84c2cdefe9e6e345731c895d 100644
|
| --- a/tests/Float16Test.cpp
|
| +++ b/tests/Float16Test.cpp
|
| @@ -55,32 +55,29 @@ DEF_TEST(color_half_float, reporter) {
|
| }
|
| }
|
|
|
| -static uint32_t u(float f) {
|
| - uint32_t x;
|
| - memcpy(&x, &f, 4);
|
| - return x;
|
| +static bool is_denorm(uint16_t h) {
|
| + return (h & 0x7fff) < 0x0400;
|
| }
|
|
|
| -DEF_TEST(HalfToFloat_finite, r) {
|
| +static bool is_finite(uint16_t h) {
|
| + return (h & 0x7c00) != 0x7c00;
|
| +}
|
| +
|
| +DEF_TEST(SkHalfToFloat_finite_ftz, r) {
|
| for (uint32_t h = 0; h <= 0xffff; h++) {
|
| - float f = SkHalfToFloat(h);
|
| - if (isfinite(f)) {
|
| - float got = SkHalfToFloat_finite(h)[0];
|
| - if (got != f) {
|
| - SkDebugf("0x%04x -> 0x%08x (%g), want 0x%08x (%g)\n",
|
| - h,
|
| - u(got), got,
|
| - u(f), f);
|
| - }
|
| - REPORTER_ASSERT(r, SkHalfToFloat_finite(h)[0] == f);
|
| - uint64_t result;
|
| - SkFloatToHalf_finite(SkHalfToFloat_finite(h)).store(&result);
|
| - REPORTER_ASSERT(r, result == h);
|
| + if (!is_finite(h)) {
|
| + // _finite_ftz() only works for values that can be represented as a finite half float.
|
| + continue;
|
| }
|
| +
|
| + // _finite_ftz() flushes denorms to zero. 0.0f will compare == with both +0.0f and -0.0f.
|
| + float expected = is_denorm(h) ? 0.0f : SkHalfToFloat(h);
|
| +
|
| + REPORTER_ASSERT(r, SkHalfToFloat_finite_ftz(h)[0] == expected);
|
| }
|
| }
|
|
|
| -DEF_TEST(FloatToHalf_finite, r) {
|
| +DEF_TEST(SkFloatToHalf_finite_ftz, r) {
|
| #if 0
|
| for (uint64_t bits = 0; bits <= 0xffffffff; bits++) {
|
| #else
|
| @@ -90,16 +87,20 @@ DEF_TEST(FloatToHalf_finite, r) {
|
| #endif
|
| float f;
|
| memcpy(&f, &bits, 4);
|
| - if (isfinite(f) && isfinite(SkHalfToFloat(SkFloatToHalf(f)))) {
|
| - uint16_t h1 = SkFloatToHalf_finite(Sk4f(f,0,0,0))[0],
|
| - h2 = SkFloatToHalf(f);
|
| - bool ok = (h1 == h2 || h1 == h2-1);
|
| - REPORTER_ASSERT(r, ok);
|
| - if (!ok) {
|
| - SkDebugf("%08x (%g) -> %04x, want %04x (%g)\n",
|
| - bits, f, h1, h2, SkHalfToFloat(h2));
|
| - break;
|
| - }
|
| +
|
| + uint16_t expected = SkFloatToHalf(f);
|
| + if (!is_finite(expected)) {
|
| + // _finite_ftz() only works for values that can be represented as a finite half float.
|
| + continue;
|
| + }
|
| +
|
| + if (is_denorm(expected)) {
|
| + // _finite_ftz() flushes denorms to zero, and happens to keep the sign bit.
|
| + expected = signbit(f) ? 0x8000 : 0x0000;
|
| }
|
| +
|
| + uint16_t actual = SkFloatToHalf_finite_ftz(Sk4f{f})[0];
|
| + // _finite_ftz() truncates instead of rounding, so it may be one too small.
|
| + REPORTER_ASSERT(r, actual == expected || actual == expected - 1);
|
| }
|
| }
|
|
|