tweak SkVx to play nicely with others Was starting to use this and ran into a few problems with clashing symbols, namely SI and cast(). Seemed simple enough to not use SI, and to move all the free-standing types into skvx: skvx::cast, skvx::shuffle, etc. Change-Id: Ia5d8ef6d0ae5375bf80d76be88d16f0c9cde56e7 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/207340 Commit-Queue: Mike Klein <mtklein@google.com> Auto-Submit: Mike Klein <mtklein@google.com> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/include/private/SkVx.h b/include/private/SkVx.h index adb6d8a..a068145 100644 --- a/include/private/SkVx.h +++ b/include/private/SkVx.h
@@ -107,7 +107,6 @@ #endif // Helps tamp down on the repetitive boilerplate. -#define SI static inline #define SIT template < typename T> static inline #define SINT template <int N, typename T> static inline #define SINTU template <int N, typename T, typename U, \ @@ -115,7 +114,7 @@ static inline template <typename D, typename S> -SI D bit_pun(S s) { +static inline D bit_pun(S s) { static_assert(sizeof(D) == sizeof(S), ""); D d; memcpy(&d, &s, sizeof(D)); @@ -160,7 +159,7 @@ // For some reason some (new!) versions of GCC cannot seem to deduce N in the generic // to_vec<N,T>() below for N=4 and T=float. This workaround seems to help... - SI Vec<4,float> to_vec(VExt<4,float> v) { return bit_pun<Vec<4,float>>(v); } + static inline Vec<4,float> to_vec(VExt<4,float> v) { return bit_pun<Vec<4,float>>(v); } #endif SINT VExt<N,T> to_vext(Vec<N,T> v) { return bit_pun<VExt<N,T>>(v); } @@ -368,20 +367,14 @@ SINT Vec<N,T>& operator<<=(Vec<N,T>& x, int bits) { return (x = x << bits); } SINT Vec<N,T>& operator>>=(Vec<N,T>& x, int bits) { return (x = x >> bits); } -} // namespace skvx - -// These next few routines take extra template arguments that prevent -// argument-dependent lookup. They must live outside the skvx namespace, -// but since they operate only on skvx::Vec, that shouldn't be a big deal. - // cast() Vec<N,S> to Vec<N,D>, as if applying a C-cast to each lane. template <typename D, typename S> -SI skvx::Vec<1,D> cast(skvx::Vec<1,S> src) { return (D)src.val; } +static inline Vec<1,D> cast(Vec<1,S> src) { return (D)src.val; } template <typename D, int N, typename S> -SI skvx::Vec<N,D> cast(skvx::Vec<N,S> src) { +static inline Vec<N,D> cast(Vec<N,S> src) { #if !defined(SKNX_NO_SIMD) && defined(__clang__) - return skvx::to_vec(__builtin_convertvector(skvx::to_vext(src), skvx::VExt<N,D>)); + return to_vec(__builtin_convertvector(to_vext(src), VExt<N,D>)); #else return join(cast<D>(src.lo), cast<D>(src.hi)); #endif @@ -395,57 +388,62 @@ // shuffle<3,3,3,3> (rgba) ~> {A,A,A,A} // The only real restriction is that the output also be a legal N=power-of-two sknx::Vec. template <int... Ix, int N, typename T> -SI skvx::Vec<sizeof...(Ix),T> shuffle(skvx::Vec<N,T> x) { +static inline Vec<sizeof...(Ix),T> shuffle(Vec<N,T> x) { return { x[Ix]... }; } #if !defined(SKNX_NO_SIMD) -namespace skvx { // Platform-specific specializations and overloads can now drop in here. -#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 - SI Vec<4,float> sqrt(Vec<4,float> x) { - return bit_pun<Vec<4,float>>(_mm_sqrt_ps(bit_pun<__m128>(x))); - } - SI Vec<4,float> rsqrt(Vec<4,float> x) { - return bit_pun<Vec<4,float>>(_mm_rsqrt_ps(bit_pun<__m128>(x))); - } - SI Vec<4,float> rcp(Vec<4,float> x) { - return bit_pun<Vec<4,float>>(_mm_rcp_ps(bit_pun<__m128>(x))); - } + #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 + static inline Vec<4,float> sqrt(Vec<4,float> x) { + return bit_pun<Vec<4,float>>(_mm_sqrt_ps(bit_pun<__m128>(x))); + } + static inline Vec<4,float> rsqrt(Vec<4,float> x) { + return bit_pun<Vec<4,float>>(_mm_rsqrt_ps(bit_pun<__m128>(x))); + } + static inline Vec<4,float> rcp(Vec<4,float> x) { + return bit_pun<Vec<4,float>>(_mm_rcp_ps(bit_pun<__m128>(x))); + } - SI Vec<2,float> sqrt(Vec<2,float> x) { return shuffle<0,1>( sqrt(shuffle<0,1,0,1>(x))); } - SI Vec<2,float> rsqrt(Vec<2,float> x) { return shuffle<0,1>(rsqrt(shuffle<0,1,0,1>(x))); } - SI Vec<2,float> rcp(Vec<2,float> x) { return shuffle<0,1>( rcp(shuffle<0,1,0,1>(x))); } -#endif + static inline Vec<2,float> sqrt(Vec<2,float> x) { + return shuffle<0,1>( sqrt(shuffle<0,1,0,1>(x))); + } + static inline Vec<2,float> rsqrt(Vec<2,float> x) { + return shuffle<0,1>(rsqrt(shuffle<0,1,0,1>(x))); + } + static inline Vec<2,float> rcp(Vec<2,float> x) { + return shuffle<0,1>( rcp(shuffle<0,1,0,1>(x))); + } + #endif -#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41 - SI Vec<4,float> if_then_else(Vec<4,int> c, Vec<4,float> t, Vec<4,float> e) { - return bit_pun<Vec<4,float>>(_mm_blendv_ps(bit_pun<__m128>(e), - bit_pun<__m128>(t), - bit_pun<__m128>(c))); - } -#elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 - SI Vec<4,float> if_then_else(Vec<4,int> c, Vec<4,float> t, Vec<4,float> e) { - return bit_pun<Vec<4,float>>(_mm_or_ps(_mm_and_ps (bit_pun<__m128>(c), - bit_pun<__m128>(t)), - _mm_andnot_ps(bit_pun<__m128>(c), - bit_pun<__m128>(e)))); - } -#elif defined(SK_ARM_HAS_NEON) - SI Vec<4,float> if_then_else(Vec<4,int> c, Vec<4,float> t, Vec<4,float> e) { - return bit_pun<Vec<4,float>>(vbslq_f32(bit_pun<uint32x4_t> (c), - bit_pun<float32x4_t>(t), - bit_pun<float32x4_t>(e))); - } -#endif + #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41 + static inline Vec<4,float> if_then_else(Vec<4,int> c, Vec<4,float> t, Vec<4,float> e) { + return bit_pun<Vec<4,float>>(_mm_blendv_ps(bit_pun<__m128>(e), + bit_pun<__m128>(t), + bit_pun<__m128>(c))); + } + #elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 + static inline Vec<4,float> if_then_else(Vec<4,int> c, Vec<4,float> t, Vec<4,float> e) { + return bit_pun<Vec<4,float>>(_mm_or_ps(_mm_and_ps (bit_pun<__m128>(c), + bit_pun<__m128>(t)), + _mm_andnot_ps(bit_pun<__m128>(c), + bit_pun<__m128>(e)))); + } + #elif defined(SK_ARM_HAS_NEON) + static inline Vec<4,float> if_then_else(Vec<4,int> c, Vec<4,float> t, Vec<4,float> e) { + return bit_pun<Vec<4,float>>(vbslq_f32(bit_pun<uint32x4_t> (c), + bit_pun<float32x4_t>(t), + bit_pun<float32x4_t>(e))); + } + #endif + +#endif // !defined(SKNX_NO_SIMD) } // namespace skvx -#endif // !defined(SKNX_NO_SIMD) #undef SINTU #undef SINT #undef SIT -#undef SI #endif//SKVX_DEFINED
diff --git a/tests/SkVxTest.cpp b/tests/SkVxTest.cpp index 61f6621..71c8fba 100644 --- a/tests/SkVxTest.cpp +++ b/tests/SkVxTest.cpp
@@ -112,7 +112,7 @@ REPORTER_ASSERT(r, all( rcp(float2{2,3}) < float2{1.0f,0.5f})); REPORTER_ASSERT(r, all(rsqrt(float2{2,3}) < float2{1.0f,1.0f})); - REPORTER_ASSERT(r, all(cast<int>(float4{-1.5f,0.5f,1.0f,1.5f}) == int4{-1,0,1,1})); + REPORTER_ASSERT(r, all(skvx::cast<int>(float4{-1.5f,0.5f,1.0f,1.5f}) == int4{-1,0,1,1})); float buf[] = {1,2,3,4,5,6}; REPORTER_ASSERT(r, all(float4::Load(buf) == float4{1,2,3,4})); @@ -128,10 +128,11 @@ REPORTER_ASSERT(r, all(mad(float4{1,2,3,4}, 2.0f, 3.0f) == float4{5,7,9,11})); - REPORTER_ASSERT(r, all(shuffle<2,1,0,3> (float4{1,2,3,4}) == float4{3,2,1,4})); - REPORTER_ASSERT(r, all(shuffle<2,1> (float4{1,2,3,4}) == float2{3,2})); - REPORTER_ASSERT(r, all(shuffle<2,1,2,1,2,1,2,1>(float4{1,2,3,4}) == float8{3,2,3,2,3,2,3,2})); - REPORTER_ASSERT(r, all(shuffle<3,3,3,3> (float4{1,2,3,4}) == float4{4,4,4,4})); + REPORTER_ASSERT(r, all(skvx::shuffle<2,1,0,3> (float4{1,2,3,4}) == float4{3,2,1,4})); + REPORTER_ASSERT(r, all(skvx::shuffle<2,1> (float4{1,2,3,4}) == float2{3,2})); + REPORTER_ASSERT(r, all(skvx::shuffle<3,3,3,3> (float4{1,2,3,4}) == float4{4,4,4,4})); + REPORTER_ASSERT(r, all(skvx::shuffle<2,1,2,1,2,1,2,1>(float4{1,2,3,4}) + == float8{3,2,3,2,3,2,3,2})); // Test that mixed types can be used where they make sense. Mostly about ergonomics. REPORTER_ASSERT(r, all(float4{1,2,3,4} < 5));