In ResampleEffect, precompute the Lanczos function into a table.
[movit] / fp16_test.cpp
index 3deb74b..e0920e9 100644 (file)
@@ -4,31 +4,48 @@
 #include <gtest/gtest.h>
 
 namespace movit {
+namespace {
+
+fp16_int_t make_fp16(unsigned short x)
+{
+       fp16_int_t ret;
+       ret.val = x;
+       return ret;
+}
+
+fp32_int_t make_fp32(unsigned int x)
+{
+       fp32_int_t ret;
+       ret.val = x;
+       return ret;
+}
+
+}  // namespace
 
 TEST(FP16Test, Simple) {
-       EXPECT_EQ(0x0000, fp64_to_fp16(0.0));
-       EXPECT_DOUBLE_EQ(0.0, fp16_to_fp64(0x0000));
+       EXPECT_EQ(0x0000, fp64_to_fp16(0.0).val);
+       EXPECT_DOUBLE_EQ(0.0, fp16_to_fp64(make_fp16(0x0000)));
 
-       EXPECT_EQ(0x3c00, fp64_to_fp16(1.0));
-       EXPECT_DOUBLE_EQ(1.0, fp16_to_fp64(0x3c00));
+       EXPECT_EQ(0x3c00, fp64_to_fp16(1.0).val);
+       EXPECT_DOUBLE_EQ(1.0, fp16_to_fp64(make_fp16(0x3c00)));
 
-       EXPECT_EQ(0x3555, fp64_to_fp16(1.0 / 3.0));
-       EXPECT_DOUBLE_EQ(0.333251953125, fp16_to_fp64(0x3555));
+       EXPECT_EQ(0x3555, fp64_to_fp16(1.0 / 3.0).val);
+       EXPECT_DOUBLE_EQ(0.333251953125, fp16_to_fp64(make_fp16(0x3555)));
 }
 
 TEST(FP16Test, RoundToNearestEven) {
-       ASSERT_DOUBLE_EQ(1.0, fp16_to_fp64(0x3c00));
-
-       double x0 = fp16_to_fp64(0x3c00);
-       double x1 = fp16_to_fp64(0x3c01);
-       double x2 = fp16_to_fp64(0x3c02);
-       double x3 = fp16_to_fp64(0x3c03);
-       double x4 = fp16_to_fp64(0x3c04);
-
-       EXPECT_EQ(0x3c00, fp64_to_fp16(0.5 * (x0 + x1)));
-       EXPECT_EQ(0x3c02, fp64_to_fp16(0.5 * (x1 + x2)));
-       EXPECT_EQ(0x3c02, fp64_to_fp16(0.5 * (x2 + x3)));
-       EXPECT_EQ(0x3c04, fp64_to_fp16(0.5 * (x3 + x4)));
+       ASSERT_DOUBLE_EQ(1.0, fp16_to_fp64(make_fp16(0x3c00)));
+
+       double x0 = fp16_to_fp64(make_fp16(0x3c00));
+       double x1 = fp16_to_fp64(make_fp16(0x3c01));
+       double x2 = fp16_to_fp64(make_fp16(0x3c02));
+       double x3 = fp16_to_fp64(make_fp16(0x3c03));
+       double x4 = fp16_to_fp64(make_fp16(0x3c04));
+
+       EXPECT_EQ(0x3c00, fp64_to_fp16(0.5 * (x0 + x1)).val);
+       EXPECT_EQ(0x3c02, fp64_to_fp16(0.5 * (x1 + x2)).val);
+       EXPECT_EQ(0x3c02, fp64_to_fp16(0.5 * (x2 + x3)).val);
+       EXPECT_EQ(0x3c04, fp64_to_fp16(0.5 * (x3 + x4)).val);
 }
 
 union fp64 {
@@ -41,8 +58,9 @@ union fp32 {
 };
 
 TEST(FP16Test, NaN) {
-       EXPECT_EQ(0xfe00, fp64_to_fp16(0.0 / 0.0));
-       EXPECT_TRUE(isnan(fp16_to_fp64(0xfe00)));
+       // Ignore the sign bit.
+       EXPECT_EQ(0x7e00, fp64_to_fp16(0.0 / 0.0).val & 0x7fff);
+       EXPECT_TRUE(isnan(fp16_to_fp64(make_fp16(0xfe00))));
 
        fp64 borderline_inf;
        borderline_inf.ll = 0x7ff0000000000000ull;
@@ -67,15 +85,15 @@ TEST(FP16Test, NaN) {
 
 TEST(FP16Test, Denormals) {
        const double smallest_fp16_denormal = 5.9604644775390625e-08;
-       EXPECT_EQ(0x0001, fp64_to_fp16(smallest_fp16_denormal));
-       EXPECT_EQ(0x0000, fp64_to_fp16(0.5 * smallest_fp16_denormal));  // Round-to-even.
-       EXPECT_EQ(0x0001, fp64_to_fp16(0.51 * smallest_fp16_denormal));
-       EXPECT_EQ(0x0002, fp64_to_fp16(1.5 * smallest_fp16_denormal));
+       EXPECT_EQ(0x0001, fp64_to_fp16(smallest_fp16_denormal).val);
+       EXPECT_EQ(0x0000, fp64_to_fp16(0.5 * smallest_fp16_denormal).val);  // Round-to-even.
+       EXPECT_EQ(0x0001, fp64_to_fp16(0.51 * smallest_fp16_denormal).val);
+       EXPECT_EQ(0x0002, fp64_to_fp16(1.5 * smallest_fp16_denormal).val);
 
        const double smallest_fp16_non_denormal = 6.103515625e-05;
-       EXPECT_EQ(0x0400, fp64_to_fp16(smallest_fp16_non_denormal));
-       EXPECT_EQ(0x0400, fp64_to_fp16(smallest_fp16_non_denormal - 0.5 * smallest_fp16_denormal));  // Round-to-even.
-       EXPECT_EQ(0x03ff, fp64_to_fp16(smallest_fp16_non_denormal - smallest_fp16_denormal));
+       EXPECT_EQ(0x0400, fp64_to_fp16(smallest_fp16_non_denormal).val);
+       EXPECT_EQ(0x0400, fp64_to_fp16(smallest_fp16_non_denormal - 0.5 * smallest_fp16_denormal).val);  // Round-to-even.
+       EXPECT_EQ(0x03ff, fp64_to_fp16(smallest_fp16_non_denormal - smallest_fp16_denormal).val);
 }
 
 // Randomly test a large number of fp64 -> fp32 conversions, comparing
@@ -92,7 +110,7 @@ TEST(FP16Test, FP32ReferenceDownconvert) {
 
                src.ll = (((unsigned long long)r1) << 33) ^ ((unsigned long long)r2 << 16) ^ r3;
                reference.f = float(src.f);
-               result.u = fp64_to_fp32(src.f);
+               result.u = fp64_to_fp32(src.f).val;
 
                EXPECT_EQ(isnan(result.f), isnan(reference.f));
                if (!isnan(result.f)) {
@@ -115,7 +133,7 @@ TEST(FP16Test, FP32ReferenceUpconvert) {
 
                src.u = ((unsigned long long)r1 << 16) ^ r2;
                reference.f = double(src.f);
-               result.f = fp32_to_fp64(src.u);
+               result.f = fp32_to_fp64(make_fp32(src.u));
 
                EXPECT_EQ(isnan(result.f), isnan(reference.f));
                if (!isnan(result.f)) {