1c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein/* 2c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein * Copyright 2015 Google Inc. 3c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein * 4c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein * Use of this source code is governed by a BSD-style license that can be 5c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein * found in the LICENSE file. 6c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein */ 7c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 8374787534147f3a616925d297bce74ff575d8911mtklein#include "Sk4px.h" 9c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein#include "SkNx.h" 1027e517ae533775889c98c65fa2f07b98357ecbc2mtklein#include "SkRandom.h" 11c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein#include "Test.h" 12c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 136f797092d2054f79374fb98fc1d57ca3554c7db4mtkleintemplate <int N> 14c9adb05b64fa0bfadf9d1a782afcda470da68c9emtkleinstatic void test_Nf(skiatest::Reporter* r) { 15c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 166c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein auto assert_nearly_eq = [&](float eps, const SkNx<N, float>& v, 176c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein float a, float b, float c, float d) { 186f797092d2054f79374fb98fc1d57ca3554c7db4mtklein auto close = [=](float a, float b) { return fabsf(a-b) <= eps; }; 196f797092d2054f79374fb98fc1d57ca3554c7db4mtklein float vals[4]; 20c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein v.store(vals); 21a156a8ffbe1342a9c329e66ad1438934ac309d70mtklein bool ok = close(vals[0], a) && close(vals[1], b) 227c249e531900929c2fe2cdde76619fa6d2538c49mtklein && close( v[0], a) && close( v[1], b); 23a156a8ffbe1342a9c329e66ad1438934ac309d70mtklein REPORTER_ASSERT(r, ok); 24c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein if (N == 4) { 25a156a8ffbe1342a9c329e66ad1438934ac309d70mtklein ok = close(vals[2], c) && close(vals[3], d) 267c249e531900929c2fe2cdde76619fa6d2538c49mtklein && close( v[2], c) && close( v[3], d); 27a156a8ffbe1342a9c329e66ad1438934ac309d70mtklein REPORTER_ASSERT(r, ok); 28c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein } 29c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein }; 306c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein auto assert_eq = [&](const SkNx<N, float>& v, float a, float b, float c, float d) { 31c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein return assert_nearly_eq(0, v, a,b,c,d); 32c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein }; 33c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 346f797092d2054f79374fb98fc1d57ca3554c7db4mtklein float vals[] = {3, 4, 5, 6}; 356c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein SkNx<N,float> a = SkNx<N,float>::Load(vals), 366c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein b(a), 376c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein c = a; 386c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein SkNx<N,float> d; 39c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein d = a; 40c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 41c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(a, 3, 4, 5, 6); 42c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(b, 3, 4, 5, 6); 43c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(c, 3, 4, 5, 6); 44c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(d, 3, 4, 5, 6); 45c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 46c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(a+b, 6, 8, 10, 12); 47c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(a*b, 9, 16, 25, 36); 48c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(a*b-b, 6, 12, 20, 30); 49c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq((a*b).sqrt(), 3, 4, 5, 6); 50c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(a/b, 1, 1, 1, 1); 516c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein assert_eq(SkNx<N,float>(0)-a, -3, -4, -5, -6); 52c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 536c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein SkNx<N,float> fours(4); 54c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 55c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein assert_eq(fours.sqrt(), 2,2,2,2); 56f8f90e4a85638faa18e7b4133cfe4d1ff5b1b23emtklein assert_nearly_eq(0.001f, fours.rsqrt(), 0.5, 0.5, 0.5, 0.5); 57c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 58f8f90e4a85638faa18e7b4133cfe4d1ff5b1b23emtklein assert_nearly_eq(0.001f, fours.invert(), 0.25, 0.25, 0.25, 0.25); 59c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 606c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein assert_eq(SkNx<N,float>::Min(a, fours), 3, 4, 4, 4); 616c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein assert_eq(SkNx<N,float>::Max(a, fours), 4, 4, 5, 6); 62c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 63c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein // Test some comparisons. This is not exhaustive. 64c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, (a == b).allTrue()); 65c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, (a+b == a*b-b).anyTrue()); 66c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, !(a+b == a*b-b).allTrue()); 67c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, !(a+b == a*b).anyTrue()); 68c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, !(a != b).anyTrue()); 69c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, (a < fours).anyTrue()); 70c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, (a <= fours).anyTrue()); 71c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, !(a > fours).allTrue()); 72c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein REPORTER_ASSERT(r, !(a >= fours).allTrue()); 73c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein} 74c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein 75c9adb05b64fa0bfadf9d1a782afcda470da68c9emtkleinDEF_TEST(SkNf, r) { 766f797092d2054f79374fb98fc1d57ca3554c7db4mtklein test_Nf<2>(r); 776f797092d2054f79374fb98fc1d57ca3554c7db4mtklein test_Nf<4>(r); 78c9adb05b64fa0bfadf9d1a782afcda470da68c9emtklein} 79115acee9386e685f9a5938fb2cf13fd5a475012amtklein 80115acee9386e685f9a5938fb2cf13fd5a475012amtkleintemplate <int N, typename T> 81115acee9386e685f9a5938fb2cf13fd5a475012amtkleinvoid test_Ni(skiatest::Reporter* r) { 826c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein auto assert_eq = [&](const SkNx<N,T>& v, T a, T b, T c, T d, T e, T f, T g, T h) { 83115acee9386e685f9a5938fb2cf13fd5a475012amtklein T vals[8]; 84115acee9386e685f9a5938fb2cf13fd5a475012amtklein v.store(vals); 85115acee9386e685f9a5938fb2cf13fd5a475012amtklein 86115acee9386e685f9a5938fb2cf13fd5a475012amtklein switch (N) { 87115acee9386e685f9a5938fb2cf13fd5a475012amtklein case 8: REPORTER_ASSERT(r, vals[4] == e && vals[5] == f && vals[6] == g && vals[7] == h); 88115acee9386e685f9a5938fb2cf13fd5a475012amtklein case 4: REPORTER_ASSERT(r, vals[2] == c && vals[3] == d); 89115acee9386e685f9a5938fb2cf13fd5a475012amtklein case 2: REPORTER_ASSERT(r, vals[0] == a && vals[1] == b); 90115acee9386e685f9a5938fb2cf13fd5a475012amtklein } 911113da72eced20480491bb87ade0ffcff4eb8ea7mtklein switch (N) { 927c249e531900929c2fe2cdde76619fa6d2538c49mtklein case 8: REPORTER_ASSERT(r, v[4] == e && v[5] == f && 937c249e531900929c2fe2cdde76619fa6d2538c49mtklein v[6] == g && v[7] == h); 947c249e531900929c2fe2cdde76619fa6d2538c49mtklein case 4: REPORTER_ASSERT(r, v[2] == c && v[3] == d); 957c249e531900929c2fe2cdde76619fa6d2538c49mtklein case 2: REPORTER_ASSERT(r, v[0] == a && v[1] == b); 961113da72eced20480491bb87ade0ffcff4eb8ea7mtklein } 97115acee9386e685f9a5938fb2cf13fd5a475012amtklein }; 98115acee9386e685f9a5938fb2cf13fd5a475012amtklein 99115acee9386e685f9a5938fb2cf13fd5a475012amtklein T vals[] = { 1,2,3,4,5,6,7,8 }; 1006c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein SkNx<N,T> a = SkNx<N,T>::Load(vals), 101115acee9386e685f9a5938fb2cf13fd5a475012amtklein b(a), 102115acee9386e685f9a5938fb2cf13fd5a475012amtklein c = a; 1036c221b40680ff933c7b8f2ac3dfa76b5732aee3emtklein SkNx<N,T> d; 104115acee9386e685f9a5938fb2cf13fd5a475012amtklein d = a; 105115acee9386e685f9a5938fb2cf13fd5a475012amtklein 106115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(a, 1,2,3,4,5,6,7,8); 107115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(b, 1,2,3,4,5,6,7,8); 108115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(c, 1,2,3,4,5,6,7,8); 109115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(d, 1,2,3,4,5,6,7,8); 110115acee9386e685f9a5938fb2cf13fd5a475012amtklein 111115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(a+a, 2,4,6,8,10,12,14,16); 112115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(a*a, 1,4,9,16,25,36,49,64); 113115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(a*a-a, 0,2,6,12,20,30,42,56); 114115acee9386e685f9a5938fb2cf13fd5a475012amtklein 115115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(a >> 2, 0,0,0,1,1,1,1,2); 116115acee9386e685f9a5938fb2cf13fd5a475012amtklein assert_eq(a << 1, 2,4,6,8,10,12,14,16); 117115acee9386e685f9a5938fb2cf13fd5a475012amtklein 1187c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, a[1] == 2); 119115acee9386e685f9a5938fb2cf13fd5a475012amtklein} 120115acee9386e685f9a5938fb2cf13fd5a475012amtklein 1216c221b40680ff933c7b8f2ac3dfa76b5732aee3emtkleinDEF_TEST(SkNx, r) { 122115acee9386e685f9a5938fb2cf13fd5a475012amtklein test_Ni<2, uint16_t>(r); 123115acee9386e685f9a5938fb2cf13fd5a475012amtklein test_Ni<4, uint16_t>(r); 124115acee9386e685f9a5938fb2cf13fd5a475012amtklein test_Ni<8, uint16_t>(r); 1251113da72eced20480491bb87ade0ffcff4eb8ea7mtklein 1261113da72eced20480491bb87ade0ffcff4eb8ea7mtklein test_Ni<2, int>(r); 1271113da72eced20480491bb87ade0ffcff4eb8ea7mtklein test_Ni<4, int>(r); 1281113da72eced20480491bb87ade0ffcff4eb8ea7mtklein test_Ni<8, int>(r); 129115acee9386e685f9a5938fb2cf13fd5a475012amtklein} 13027e517ae533775889c98c65fa2f07b98357ecbc2mtklein 131e20633ed26d211e8d2b4b407c7e968944c7e60bbmtkleinDEF_TEST(SkNi_min_lt, r) { 13227e517ae533775889c98c65fa2f07b98357ecbc2mtklein // Exhaustively check the 8x8 bit space. 13327e517ae533775889c98c65fa2f07b98357ecbc2mtklein for (int a = 0; a < (1<<8); a++) { 13427e517ae533775889c98c65fa2f07b98357ecbc2mtklein for (int b = 0; b < (1<<8); b++) { 135e20633ed26d211e8d2b4b407c7e968944c7e60bbmtklein Sk16b aw(a), bw(b); 1367c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, Sk16b::Min(aw, bw)[0] == SkTMin(a, b)); 1377c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, !(aw < bw)[0] == !(a < b)); 13827e517ae533775889c98c65fa2f07b98357ecbc2mtklein }} 13927e517ae533775889c98c65fa2f07b98357ecbc2mtklein 14027e517ae533775889c98c65fa2f07b98357ecbc2mtklein // Exhausting the 16x16 bit space is kind of slow, so only do that in release builds. 14127e517ae533775889c98c65fa2f07b98357ecbc2mtklein#ifdef SK_DEBUG 14227e517ae533775889c98c65fa2f07b98357ecbc2mtklein SkRandom rand; 14327e517ae533775889c98c65fa2f07b98357ecbc2mtklein for (int i = 0; i < (1<<16); i++) { 14427e517ae533775889c98c65fa2f07b98357ecbc2mtklein uint16_t a = rand.nextU() >> 16, 14527e517ae533775889c98c65fa2f07b98357ecbc2mtklein b = rand.nextU() >> 16; 1467c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, Sk16h::Min(Sk16h(a), Sk16h(b))[0] == SkTMin(a, b)); 14727e517ae533775889c98c65fa2f07b98357ecbc2mtklein } 14827e517ae533775889c98c65fa2f07b98357ecbc2mtklein#else 14927e517ae533775889c98c65fa2f07b98357ecbc2mtklein for (int a = 0; a < (1<<16); a++) { 15027e517ae533775889c98c65fa2f07b98357ecbc2mtklein for (int b = 0; b < (1<<16); b++) { 1517c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, Sk16h::Min(Sk16h(a), Sk16h(b))[0] == SkTMin(a, b)); 15227e517ae533775889c98c65fa2f07b98357ecbc2mtklein }} 15327e517ae533775889c98c65fa2f07b98357ecbc2mtklein#endif 15427e517ae533775889c98c65fa2f07b98357ecbc2mtklein} 155374787534147f3a616925d297bce74ff575d8911mtklein 156374787534147f3a616925d297bce74ff575d8911mtkleinDEF_TEST(SkNi_saturatedAdd, r) { 157374787534147f3a616925d297bce74ff575d8911mtklein for (int a = 0; a < (1<<8); a++) { 158374787534147f3a616925d297bce74ff575d8911mtklein for (int b = 0; b < (1<<8); b++) { 159374787534147f3a616925d297bce74ff575d8911mtklein int exact = a+b; 160374787534147f3a616925d297bce74ff575d8911mtklein if (exact > 255) { exact = 255; } 161374787534147f3a616925d297bce74ff575d8911mtklein if (exact < 0) { exact = 0; } 162374787534147f3a616925d297bce74ff575d8911mtklein 1637c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, Sk16b(a).saturatedAdd(Sk16b(b))[0] == exact); 164374787534147f3a616925d297bce74ff575d8911mtklein } 165374787534147f3a616925d297bce74ff575d8911mtklein } 166374787534147f3a616925d297bce74ff575d8911mtklein} 167374787534147f3a616925d297bce74ff575d8911mtklein 168374787534147f3a616925d297bce74ff575d8911mtkleinDEF_TEST(Sk4px_muldiv255round, r) { 169374787534147f3a616925d297bce74ff575d8911mtklein for (int a = 0; a < (1<<8); a++) { 170374787534147f3a616925d297bce74ff575d8911mtklein for (int b = 0; b < (1<<8); b++) { 171374787534147f3a616925d297bce74ff575d8911mtklein int exact = (a*b+127)/255; 172374787534147f3a616925d297bce74ff575d8911mtklein 173374787534147f3a616925d297bce74ff575d8911mtklein // Duplicate a and b 16x each. 174059ac00446404506a46cd303db15239c7aae49d5mtklein auto av = Sk4px::DupAlpha(a), 175059ac00446404506a46cd303db15239c7aae49d5mtklein bv = Sk4px::DupAlpha(b); 176374787534147f3a616925d297bce74ff575d8911mtklein 177374787534147f3a616925d297bce74ff575d8911mtklein // This way should always be exactly correct. 1787c249e531900929c2fe2cdde76619fa6d2538c49mtklein int correct = (av * bv).div255()[0]; 179374787534147f3a616925d297bce74ff575d8911mtklein REPORTER_ASSERT(r, correct == exact); 180374787534147f3a616925d297bce74ff575d8911mtklein 181374787534147f3a616925d297bce74ff575d8911mtklein // We're a bit more flexible on this method: correct for 0 or 255, otherwise off by <=1. 1827c249e531900929c2fe2cdde76619fa6d2538c49mtklein int fast = av.approxMulDiv255(bv)[0]; 183374787534147f3a616925d297bce74ff575d8911mtklein REPORTER_ASSERT(r, fast-exact >= -1 && fast-exact <= 1); 184374787534147f3a616925d297bce74ff575d8911mtklein if (a == 0 || a == 255 || b == 0 || b == 255) { 185374787534147f3a616925d297bce74ff575d8911mtklein REPORTER_ASSERT(r, fast == exact); 186374787534147f3a616925d297bce74ff575d8911mtklein } 187374787534147f3a616925d297bce74ff575d8911mtklein } 188374787534147f3a616925d297bce74ff575d8911mtklein } 189374787534147f3a616925d297bce74ff575d8911mtklein} 1904be181e304d2b280c6801bd13369cfba236d1a66mtklein 1914be181e304d2b280c6801bd13369cfba236d1a66mtkleinDEF_TEST(Sk4px_widening, r) { 1924be181e304d2b280c6801bd13369cfba236d1a66mtklein SkPMColor colors[] = { 1934be181e304d2b280c6801bd13369cfba236d1a66mtklein SkPreMultiplyColor(0xff00ff00), 1944be181e304d2b280c6801bd13369cfba236d1a66mtklein SkPreMultiplyColor(0x40008000), 1954be181e304d2b280c6801bd13369cfba236d1a66mtklein SkPreMultiplyColor(0x7f020406), 1964be181e304d2b280c6801bd13369cfba236d1a66mtklein SkPreMultiplyColor(0x00000000), 1974be181e304d2b280c6801bd13369cfba236d1a66mtklein }; 1984be181e304d2b280c6801bd13369cfba236d1a66mtklein auto packed = Sk4px::Load4(colors); 1994be181e304d2b280c6801bd13369cfba236d1a66mtklein 2004be181e304d2b280c6801bd13369cfba236d1a66mtklein auto wideLo = packed.widenLo(), 2014be181e304d2b280c6801bd13369cfba236d1a66mtklein wideHi = packed.widenHi(), 2024be181e304d2b280c6801bd13369cfba236d1a66mtklein wideLoHi = packed.widenLoHi(), 2034be181e304d2b280c6801bd13369cfba236d1a66mtklein wideLoHiAlt = wideLo + wideHi; 2044be181e304d2b280c6801bd13369cfba236d1a66mtklein REPORTER_ASSERT(r, 0 == memcmp(&wideLoHi, &wideLoHiAlt, sizeof(wideLoHi))); 2054be181e304d2b280c6801bd13369cfba236d1a66mtklein} 206a508f3c62d726867ad9f722623fbf0ab5d06e440mtklein 207c33065a93ad0874672c4c66b9711aa0b3ef7b7e7mtkleinDEF_TEST(SkNx_abs, r) { 208c33065a93ad0874672c4c66b9711aa0b3ef7b7e7mtklein auto fs = Sk4f(0.0f, -0.0f, 2.0f, -4.0f).abs(); 2097c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[0] == 0.0f); 2107c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[1] == 0.0f); 2117c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[2] == 2.0f); 2127c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[3] == 4.0f); 213c33065a93ad0874672c4c66b9711aa0b3ef7b7e7mtklein} 214629f25a7ef229d97e22530eae043882b20cd8d8cmtklein 2157da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian LiDEF_TEST(Sk4i_abs, r) { 2167da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li auto is = Sk4i(0, -1, 2, -2147483647).abs(); 2177da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li REPORTER_ASSERT(r, is[0] == 0); 2187da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li REPORTER_ASSERT(r, is[1] == 1); 2197da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li REPORTER_ASSERT(r, is[2] == 2); 2207da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li REPORTER_ASSERT(r, is[3] == 2147483647); 2217da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li} 2227da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li 2237da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian LiDEF_TEST(Sk4i_minmax, r) { 2247da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li auto a = Sk4i(0, 2, 4, 6); 2257da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li auto b = Sk4i(1, 1, 3, 7); 2267da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li auto min = Sk4i::Min(a, b); 2277da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li auto max = Sk4i::Max(a, b); 2287da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li for(int i = 0; i < 4; ++i) { 2297da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li REPORTER_ASSERT(r, min[i] == SkTMin(a[i], b[i])); 2307da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li REPORTER_ASSERT(r, max[i] == SkTMax(a[i], b[i])); 2317da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li } 2327da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li} 2337da6ba2d63cfd5ae6add617f18ba4882e755642bYuqian Li 234126626e52310b39429ad5eaa8e68e0caa24e6202mtkleinDEF_TEST(SkNx_floor, r) { 235126626e52310b39429ad5eaa8e68e0caa24e6202mtklein auto fs = Sk4f(0.4f, -0.4f, 0.6f, -0.6f).floor(); 2367c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[0] == 0.0f); 2377c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[1] == -1.0f); 2387c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[2] == 0.0f); 2397c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, fs[3] == -1.0f); 240126626e52310b39429ad5eaa8e68e0caa24e6202mtklein} 241126626e52310b39429ad5eaa8e68e0caa24e6202mtklein 242e4c0beed744d09dae4757c1893d8caa64ee09cd2mtkleinDEF_TEST(SkNx_shuffle, r) { 243e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein Sk4f f4(0,10,20,30); 244629f25a7ef229d97e22530eae043882b20cd8d8cmtklein 245e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein Sk2f f2 = SkNx_shuffle<2,1>(f4); 246e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein REPORTER_ASSERT(r, f2[0] == 20); 247e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein REPORTER_ASSERT(r, f2[1] == 10); 248e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein 249e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein f4 = SkNx_shuffle<0,1,1,0>(f2); 250e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein REPORTER_ASSERT(r, f4[0] == 20); 251e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein REPORTER_ASSERT(r, f4[1] == 10); 252e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein REPORTER_ASSERT(r, f4[2] == 10); 253e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein REPORTER_ASSERT(r, f4[3] == 20); 254629f25a7ef229d97e22530eae043882b20cd8d8cmtklein} 255629f25a7ef229d97e22530eae043882b20cd8d8cmtklein 2560cf795fd1135babe0ee0b3585f3ad49a02fe1387mtkleinDEF_TEST(SkNx_int_float, r) { 2570cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein Sk4f f(-2.3f, 1.0f, 0.45f, 0.6f); 2580cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein 2590cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein Sk4i i = SkNx_cast<int>(f); 2600cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, i[0] == -2); 2610cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, i[1] == 1); 2620cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, i[2] == 0); 2630cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, i[3] == 0); 2640cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein 2650cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein f = SkNx_cast<float>(i); 2660cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, f[0] == -2.0f); 2670cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, f[1] == 1.0f); 2680cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, f[2] == 0.0f); 2690cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein REPORTER_ASSERT(r, f[3] == 0.0f); 2700cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein} 2710cf795fd1135babe0ee0b3585f3ad49a02fe1387mtklein 272e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein#include "SkRandom.h" 273e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein 274629f25a7ef229d97e22530eae043882b20cd8d8cmtkleinDEF_TEST(SkNx_u16_float, r) { 275629f25a7ef229d97e22530eae043882b20cd8d8cmtklein { 276629f25a7ef229d97e22530eae043882b20cd8d8cmtklein // u16 --> float 277629f25a7ef229d97e22530eae043882b20cd8d8cmtklein auto h4 = Sk4h(15, 17, 257, 65535); 278629f25a7ef229d97e22530eae043882b20cd8d8cmtklein auto f4 = SkNx_cast<float>(h4); 2797c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, f4[0] == 15.0f); 2807c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, f4[1] == 17.0f); 2817c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, f4[2] == 257.0f); 2827c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, f4[3] == 65535.0f); 283629f25a7ef229d97e22530eae043882b20cd8d8cmtklein } 284629f25a7ef229d97e22530eae043882b20cd8d8cmtklein { 285629f25a7ef229d97e22530eae043882b20cd8d8cmtklein // float -> u16 286629f25a7ef229d97e22530eae043882b20cd8d8cmtklein auto f4 = Sk4f(15, 17, 257, 65535); 287629f25a7ef229d97e22530eae043882b20cd8d8cmtklein auto h4 = SkNx_cast<uint16_t>(f4); 2887c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, h4[0] == 15); 2897c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, h4[1] == 17); 2907c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, h4[2] == 257); 2917c249e531900929c2fe2cdde76619fa6d2538c49mtklein REPORTER_ASSERT(r, h4[3] == 65535); 292629f25a7ef229d97e22530eae043882b20cd8d8cmtklein } 293629f25a7ef229d97e22530eae043882b20cd8d8cmtklein 294629f25a7ef229d97e22530eae043882b20cd8d8cmtklein // starting with any u16 value, we should be able to have a perfect round-trip in/out of floats 295629f25a7ef229d97e22530eae043882b20cd8d8cmtklein // 296629f25a7ef229d97e22530eae043882b20cd8d8cmtklein SkRandom rand; 297e4c0beed744d09dae4757c1893d8caa64ee09cd2mtklein for (int i = 0; i < 10000; ++i) { 298629f25a7ef229d97e22530eae043882b20cd8d8cmtklein const uint16_t s16[4] { 299629f25a7ef229d97e22530eae043882b20cd8d8cmtklein (uint16_t)rand.nextU16(), (uint16_t)rand.nextU16(), 300629f25a7ef229d97e22530eae043882b20cd8d8cmtklein (uint16_t)rand.nextU16(), (uint16_t)rand.nextU16(), 301629f25a7ef229d97e22530eae043882b20cd8d8cmtklein }; 302629f25a7ef229d97e22530eae043882b20cd8d8cmtklein auto u4_0 = Sk4h::Load(s16); 303629f25a7ef229d97e22530eae043882b20cd8d8cmtklein auto f4 = SkNx_cast<float>(u4_0); 304629f25a7ef229d97e22530eae043882b20cd8d8cmtklein auto u4_1 = SkNx_cast<uint16_t>(f4); 305629f25a7ef229d97e22530eae043882b20cd8d8cmtklein uint16_t d16[4]; 306629f25a7ef229d97e22530eae043882b20cd8d8cmtklein u4_1.store(d16); 307629f25a7ef229d97e22530eae043882b20cd8d8cmtklein REPORTER_ASSERT(r, !memcmp(s16, d16, sizeof(s16))); 308629f25a7ef229d97e22530eae043882b20cd8d8cmtklein } 309629f25a7ef229d97e22530eae043882b20cd8d8cmtklein} 31058e389b0518b46bbe58ba01c23443cf23c18435cmtklein 31158e389b0518b46bbe58ba01c23443cf23c18435cmtklein// The SSE2 implementation of SkNx_cast<uint16_t>(Sk4i) is non-trivial, so worth a test. 31258e389b0518b46bbe58ba01c23443cf23c18435cmtkleinDEF_TEST(SkNx_int_u16, r) { 31358e389b0518b46bbe58ba01c23443cf23c18435cmtklein // These are pretty hard to get wrong. 31458e389b0518b46bbe58ba01c23443cf23c18435cmtklein for (int i = 0; i <= 0x7fff; i++) { 31558e389b0518b46bbe58ba01c23443cf23c18435cmtklein uint16_t expected = (uint16_t)i; 31658e389b0518b46bbe58ba01c23443cf23c18435cmtklein uint16_t actual = SkNx_cast<uint16_t>(Sk4i(i))[0]; 31758e389b0518b46bbe58ba01c23443cf23c18435cmtklein 31858e389b0518b46bbe58ba01c23443cf23c18435cmtklein REPORTER_ASSERT(r, expected == actual); 31958e389b0518b46bbe58ba01c23443cf23c18435cmtklein } 32058e389b0518b46bbe58ba01c23443cf23c18435cmtklein 32158e389b0518b46bbe58ba01c23443cf23c18435cmtklein // A naive implementation with _mm_packs_epi32 would succeed up to 0x7fff but fail here: 32258e389b0518b46bbe58ba01c23443cf23c18435cmtklein for (int i = 0x8000; (1) && i <= 0xffff; i++) { 32358e389b0518b46bbe58ba01c23443cf23c18435cmtklein uint16_t expected = (uint16_t)i; 32458e389b0518b46bbe58ba01c23443cf23c18435cmtklein uint16_t actual = SkNx_cast<uint16_t>(Sk4i(i))[0]; 32558e389b0518b46bbe58ba01c23443cf23c18435cmtklein 32658e389b0518b46bbe58ba01c23443cf23c18435cmtklein REPORTER_ASSERT(r, expected == actual); 32758e389b0518b46bbe58ba01c23443cf23c18435cmtklein } 32858e389b0518b46bbe58ba01c23443cf23c18435cmtklein} 329c0444615ed76360f680619ad4d1f92cda6181a50msarett 330c0444615ed76360f680619ad4d1f92cda6181a50msarettDEF_TEST(SkNx_4fLoad4Store4, r) { 331c0444615ed76360f680619ad4d1f92cda6181a50msarett float src[] = { 332c0444615ed76360f680619ad4d1f92cda6181a50msarett 0.0f, 1.0f, 2.0f, 3.0f, 333c0444615ed76360f680619ad4d1f92cda6181a50msarett 4.0f, 5.0f, 6.0f, 7.0f, 334c0444615ed76360f680619ad4d1f92cda6181a50msarett 8.0f, 9.0f, 10.0f, 11.0f, 335c0444615ed76360f680619ad4d1f92cda6181a50msarett 12.0f, 13.0f, 14.0f, 15.0f 336c0444615ed76360f680619ad4d1f92cda6181a50msarett }; 337c0444615ed76360f680619ad4d1f92cda6181a50msarett 338c0444615ed76360f680619ad4d1f92cda6181a50msarett Sk4f a, b, c, d; 33933cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4f::Load4(src, &a, &b, &c, &d); 340c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 0.0f == a[0]); 341c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 4.0f == a[1]); 342c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 8.0f == a[2]); 343c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 12.0f == a[3]); 344c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 1.0f == b[0]); 345c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 5.0f == b[1]); 346c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 9.0f == b[2]); 347c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 13.0f == b[3]); 348c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 2.0f == c[0]); 349c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 6.0f == c[1]); 350c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 10.0f == c[2]); 351c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 14.0f == c[3]); 352c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 3.0f == d[0]); 353c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 7.0f == d[1]); 354c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 11.0f == d[2]); 355c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 15.0f == d[3]); 356c0444615ed76360f680619ad4d1f92cda6181a50msarett 357c0444615ed76360f680619ad4d1f92cda6181a50msarett float dst[16]; 35833cbfd75afdd383770bb6253c06ba819a2481a35Mike Klein Sk4f::Store4(dst, a, b, c, d); 359c0444615ed76360f680619ad4d1f92cda6181a50msarett REPORTER_ASSERT(r, 0 == memcmp(dst, src, 16 * sizeof(float))); 360c0444615ed76360f680619ad4d1f92cda6181a50msarett} 361