aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/SkNxTest.cpp
blob: af6918e38c0ec500dcf666583aa0fb660797533a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkNx.h"
#include "Test.h"

template <int N, typename T>
static void test_Nf(skiatest::Reporter* r) {

    auto assert_nearly_eq = [&](double eps, const SkNf<N,T>& v, T a, T b, T c, T d) {
        auto close = [=](T a, T b) { return fabs(a-b) <= eps; };
        T vals[4];
        v.store(vals);
        bool ok = close(vals[0], a) && close(vals[1], b)
               && close(v.template kth<0>(), a) && close(v.template kth<1>(), b);
        REPORTER_ASSERT(r, ok);
        if (N == 4) {
            ok = close(vals[2], c) && close(vals[3], d)
              && close(v.template kth<2>(), c) && close(v.template kth<3>(), d);
            REPORTER_ASSERT(r, ok);
        }
    };
    auto assert_eq = [&](const SkNf<N,T>& v, T a, T b, T c, T d) {
        return assert_nearly_eq(0, v, a,b,c,d);
    };

    T vals[] = {3, 4, 5, 6};
    SkNf<N,T> a = SkNf<N,T>::Load(vals),
              b(a),
              c = a;
    SkNf<N,T> d;
    d = a;

    assert_eq(a, 3, 4, 5, 6);
    assert_eq(b, 3, 4, 5, 6);
    assert_eq(c, 3, 4, 5, 6);
    assert_eq(d, 3, 4, 5, 6);

    assert_eq(a+b, 6, 8, 10, 12);
    assert_eq(a*b, 9, 16, 25, 36);
    assert_eq(a*b-b, 6, 12, 20, 30);
    assert_eq((a*b).sqrt(), 3, 4, 5, 6);
    assert_eq(a/b, 1, 1, 1, 1);
    assert_eq(-a, -3, -4, -5, -6);

    SkNf<N,T> fours(4);

    assert_eq(fours.sqrt(), 2,2,2,2);
    assert_nearly_eq(0.001, fours.rsqrt(), 0.5, 0.5, 0.5, 0.5);

    assert_eq(              fours.      invert(), 0.25, 0.25, 0.25, 0.25);
    assert_nearly_eq(0.001, fours.approxInvert(), 0.25, 0.25, 0.25, 0.25);

    assert_eq(SkNf<N,T>::Min(a, fours), 3, 4, 4, 4);
    assert_eq(SkNf<N,T>::Max(a, fours), 4, 4, 5, 6);

    // Test some comparisons.  This is not exhaustive.
    REPORTER_ASSERT(r, (a == b).allTrue());
    REPORTER_ASSERT(r, (a+b == a*b-b).anyTrue());
    REPORTER_ASSERT(r, !(a+b == a*b-b).allTrue());
    REPORTER_ASSERT(r, !(a+b == a*b).anyTrue());
    REPORTER_ASSERT(r, !(a != b).anyTrue());
    REPORTER_ASSERT(r, (a < fours).anyTrue());
    REPORTER_ASSERT(r, (a <= fours).anyTrue());
    REPORTER_ASSERT(r, !(a > fours).allTrue());
    REPORTER_ASSERT(r, !(a >= fours).allTrue());
}

DEF_TEST(SkNf, r) {
    test_Nf<2, float>(r);
    test_Nf<2, double>(r);

    test_Nf<4, float>(r);
    test_Nf<4, double>(r);
}

template <int N, typename T>
void test_Ni(skiatest::Reporter* r) {
    auto assert_eq = [&](const SkNi<N,T>& v, T a, T b, T c, T d, T e, T f, T g, T h) {
        T vals[8];
        v.store(vals);

        switch (N) {
          case 8: REPORTER_ASSERT(r, vals[4] == e && vals[5] == f && vals[6] == g && vals[7] == h);
          case 4: REPORTER_ASSERT(r, vals[2] == c && vals[3] == d);
          case 2: REPORTER_ASSERT(r, vals[0] == a && vals[1] == b);
        }
    };

    T vals[] = { 1,2,3,4,5,6,7,8 };
    SkNi<N,T> a = SkNi<N,T>::Load(vals),
              b(a),
              c = a;
    SkNi<N,T> d;
    d = a;

    assert_eq(a, 1,2,3,4,5,6,7,8);
    assert_eq(b, 1,2,3,4,5,6,7,8);
    assert_eq(c, 1,2,3,4,5,6,7,8);
    assert_eq(d, 1,2,3,4,5,6,7,8);

    assert_eq(a+a, 2,4,6,8,10,12,14,16);
    assert_eq(a*a, 1,4,9,16,25,36,49,64);
    assert_eq(a*a-a, 0,2,6,12,20,30,42,56);

    assert_eq(a >> 2, 0,0,0,1,1,1,1,2);
    assert_eq(a << 1, 2,4,6,8,10,12,14,16);

    REPORTER_ASSERT(r, a.template kth<1>() == 2);
}

DEF_TEST(SkNi, r) {
    test_Ni<2, uint16_t>(r);
    test_Ni<4, uint16_t>(r);
    test_Ni<8, uint16_t>(r);
}