aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkHalf.h
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2016-04-14 12:27:38 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-14 12:27:38 -0700
commitcbe3c1af987d622ea67ef560d855b41bb14a0ce9 (patch)
tree615b57bc9af7b6e1d15aa5db00ad790d1f9f037b /src/core/SkHalf.h
parentd06920a29fe11c68bde2b93948ec99f277bb8459 (diff)
skcpu: sse4.1 floor, f16c f16<->f32
- floor with roundps is about 4.5x faster when available - f16 srcover_n is similar to but a little faster than the version in https://codereview.chromium.org/1884683002. This new one fuses the dst load/stores into the f16<->f32 conversions: +0x180 movups (%r15), %xmm1 +0x184 vcvtph2ps (%rbx), %xmm2 +0x189 movaps %xmm1, %xmm3 +0x18c shufps $255, %xmm3, %xmm3 +0x190 movaps %xmm0, %xmm4 +0x193 subps %xmm3, %xmm4 +0x196 mulps %xmm2, %xmm4 +0x199 addps %xmm1, %xmm4 +0x19c vcvtps2ph $0, %xmm4, (%rbx) +0x1a2 addq $16, %r15 +0x1a6 addq $8, %rbx +0x1aa decl %r14d +0x1ad jne +0x180 If we decide to land this it'd be a good idea to convert most or all users of SkFloatToHalf_01 and SkHalfToFloat_01 over to the pointer-based versions. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1891513002 CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot Review URL: https://codereview.chromium.org/1891513002
Diffstat (limited to 'src/core/SkHalf.h')
-rw-r--r--src/core/SkHalf.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/core/SkHalf.h b/src/core/SkHalf.h
index 5f5575ae1a..e56c78c212 100644
--- a/src/core/SkHalf.h
+++ b/src/core/SkHalf.h
@@ -8,6 +8,7 @@
#ifndef SkHalf_DEFINED
#define SkHalf_DEFINED
+#include "SkCpu.h"
#include "SkNx.h"
#include "SkTypes.h"
@@ -122,3 +123,32 @@ static inline uint64_t SkFloatToHalf_01(const Sk4f& fs) {
}
#endif
+
+static inline Sk4f SkHalfToFloat_01(const uint64_t* hs) {
+#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
+ if (SkCpu::Supports(SkCpu::F16C)) {
+ __m128 fs;
+ #if defined(_MSC_VER)
+ fs = _mm_cvtph_ps(_mm_loadl_epi64((const __m128i*)hs));
+ #else
+ asm("vcvtph2ps %[hs], %[fs]" : [fs]"=x"(fs) : [hs]"m"(*hs));
+ #endif
+ return fs;
+ }
+#endif
+ return SkHalfToFloat_01(*hs);
+}
+
+static inline void SkFloatToHalf_01(const Sk4f& fs, uint64_t* hs) {
+#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
+ if (SkCpu::Supports(SkCpu::F16C)) {
+ #if defined(_MSC_VER)
+ _mm_storel_epi64((__m128i*)hs, _mm_cvtps_ph(fs.fVec, 0));
+ #else
+ asm("vcvtps2ph $0, %[fs], %[hs]" : [hs]"=m"(*hs) : [fs]"x"(fs.fVec));
+ #endif
+ return;
+ }
+#endif
+ *hs = SkFloatToHalf_01(fs);
+}