Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #ifndef Sk4x_DEFINED | |
| 2 #define Sk4x_DEFINED | |
| 3 | |
| 4 // Sk4x.h brings the fun of GCC vector extensions* to platforms without them (MS VC). | |
| 5 // We also paper over some of the differences between GCC and Clang's flavors. | |
| 6 // | |
| 7 // * https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html | |
| 8 // http://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vec tors | |
| 9 | |
| 10 // First code common to both Clang and GCC. | |
| 11 #if defined(__GNUC__) | |
| 12 typedef float Sk4f __attribute__((vector_size(16))); | |
| 13 typedef int Sk4i __attribute__((vector_size(16))); | |
| 14 #endif | |
| 15 | |
| 16 // Now code specialized for Clang xor GCC. | |
| 17 #if defined(__clang__) | |
| 18 #define Sk4Shuffle(x,y, m,a,s,k) __builtin_shufflevector(x,y, m,a,s,k) | |
| 19 | |
| 20 #if __has_builtin(__builtin_convertvector) | |
| 21 template<typename D, typename S> | |
| 22 D Sk4Convert(S src) { return __builtin_convertvector(src, D); } | |
| 23 #else | |
| 24 template<typename D, typename S> | |
| 25 D Sk4Convert(S src) { | |
| 26 D dst = { (D)src[0], (D)src[1], (D)src[2], (D)src[3] }; | |
| 27 return dst; | |
| 28 } | |
| 29 #endif | |
| 30 | |
| 31 #elif defined(__GNUC__) | |
| 32 template <typename V> | |
| 33 V Sk4Shuffle(V x, V y, int m, int a, int s, int k) { | |
| 34 Sk4i mask = { m, a, s, k }; | |
| 35 return __builtin_shuffle(x, y, mask); | |
| 36 } | |
| 37 | |
| 38 template<typename D, typename S> | |
| 39 D Sk4Convert(S src) { | |
| 40 D dst = { (D)src[0], (D)src[1], (D)src[2], (D)src[3] }; | |
| 41 return dst; | |
| 42 } | |
| 43 | |
| 44 #endif | |
| 45 | |
| 46 #if !defined(__GNUC__) | |
| 47 #error "Need to implement scalar versions." | |
| 48 #endif | |
| 49 | |
| 50 | |
| 51 // Finally code that will work no matter the implementation. | |
| 52 inline Sk4f SkLoad4f(float a, float b, float c, float d) { | |
| 53 Sk4f v = { a, b, c, d }; | |
| 54 return v; | |
| 55 } | |
| 56 | |
| 57 inline Sk4i SkLoad4i(int a, int b, int c, int d) { | |
| 58 Sk4i v = { a, b, c, d }; | |
| 59 return v; | |
| 60 } | |
| 61 | |
| 62 inline Sk4f SkLoad4f(const float fs[4]) { | |
| 63 Sk4f v = { fs[0], fs[1], fs[2], fs[3] }; | |
| 64 return v; | |
| 65 } | |
| 66 | |
| 67 inline Sk4i SkLoad4i(const int is[4]) { | |
| 68 Sk4i v = { is[0], is[1], is[2], is[3] }; | |
| 69 return v; | |
| 70 } | |
| 71 | |
| 72 inline void SkStore4(Sk4f v, float fs[4]) { | |
| 73 *reinterpret_cast<Sk4f*>(fs) = v; | |
| 74 } | |
| 75 | |
| 76 inline void SkStore4(Sk4i v, int is[4]) { | |
| 77 *reinterpret_cast<Sk4i*>(is) = v; | |
| 78 } | |
| 79 | |
| 80 inline bool Sk4All(Sk4i v) { | |
|
reed1
2014/10/10 16:06:11
as we start to actually use these, we might discus
mtklein
2014/10/10 21:26:07
See what you think of the API at PS 20?
| |
| 81 return v[0] & v[1] & v[2] & v[3]; | |
| 82 } | |
| 83 | |
| 84 template <typename V> | |
| 85 V Sk4Min(V a, V b) { | |
| 86 Sk4i less = a < b; | |
| 87 return ((Sk4i)a & less) | ((Sk4i)b & ~less); | |
| 88 } | |
| 89 | |
| 90 template <typename V> | |
| 91 V Sk4Max(V a, V b) { | |
| 92 Sk4i less = a < b; | |
| 93 return ((Sk4i)b & less) | ((Sk4i)a & ~less); | |
| 94 } | |
| 95 | |
| 96 #endif//Sk4x_DEFINED | |
| OLD | NEW |