aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/opts/SkBlitRow_opts_SSE4.cpp
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2015-01-26 14:32:09 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-01-26 14:32:09 -0800
commit2d80dd264704984bca4c2915f31ef427033b0b9b (patch)
treed107a29874b86f51c5daed12464420d7a0c96edf /src/opts/SkBlitRow_opts_SSE4.cpp
parent6bdc9cd003ccba5e19ba1fc4fbe37aa676db9d53 (diff)
Revert of SSE4 opaque blend using intrinsics instead of assembly. (patchset #14 id:260001 of https://codereview.chromium.org/874863002/)
Reason for revert: This kills Mac 10.6 bots. FAILED: c++ -MMD -MF obj/src/opts/opts_sse4.SkBlitRow_opts_SSE4.o.d -DSK_INTERNAL -DSK_GAMMA_SRGB -DSK_GAMMA_APPLY_TO_A8 -DSK_SCALAR_TO_FLOAT_EXCLUDED -DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=1 -DSK_SUPPORT_OPENCL=0 -DSK_FORCE_DISTANCE_FIELD_TEXT=0 -DSK_BUILD_FOR_MAC -DSK_CRASH_HANDLER -DSK_DEVELOPER=1 -I../../src/core -I../../src/utils -I../../include/c -I../../include/config -I../../include/core -I../../include/pathops -I../../include/pipe -I../../include/utils/mac -I../../include/effects -O0 -gdwarf-2 -mmacosx-version-min=10.6 -arch x86_64 -mssse3 -Wall -Wextra -Winit-self -Wpointer-arith -Wsign-compare -Wno-unused-parameter -Wno-invalid-offsetof -msse4.1 -c ../../src/opts/SkBlitRow_opts_SSE4.cpp -o obj/src/opts/opts_sse4.SkBlitRow_opts_SSE4.o ../../src/opts/SkBlitRow_opts_SSE4.cpp:15:27: warning: x86intrin.h: No such file or directory ../../src/opts/SkBlitRow_opts_SSE4.cpp: In function 'void S32A_Opaque_BlitRow32_SSE4(SkPMColor*, const SkPMColor*, int, U8CPU)': ../../src/opts/SkBlitRow_opts_SSE4.cpp:40: error: '_mm_testz_si128' was not declared in this scope ../../src/opts/SkBlitRow_opts_SSE4.cpp:45: error: '_mm_testc_si128' was not declared in this scope Original issue's description: > SSE4 opaque blend using intrinsics instead of assembly. > > Since we had such a hard time with the assembly versions of this blit (to the > point that we have them completely disabled everywhere), I thought I'd take > a shot at writing a version of the blit using intrinsics. > > The key feature of SSE4 we're exploiting is that we can use ptest (_mm_test*) > to skip the blend when the 16 src pixels we consider each loop are all opaque > or all transparent. _mm_shuffle_epi8 from SSSE3 also lends a hand to extract > all those alphas. > > It's worth looking to see if we can backport this type of logic to SSE2 using > _mm_movemask_epi8, or up to 32 pixels at a time using AVX. > > My local performance testing doesn't show this to be an unambiguous win > (there are probably microbenchmarks and SKPs where we'd be better off just > powering through the blend rather than looking at alphas), but the potential > does seem tantalizing enough to let skiaperf vet it on the bots. (< 1.0x is a win.) > > DM says it draws pixel perfect compare to the old code. > > Microbenchmarks: > bitmap_RGBA_8888_A_source_stripes_two 14us -> 14.4us 1.03x > bitmap_RGBA_8888_A_source_stripes_three 14.3us -> 14.5us 1.01x > bitmap_RGBA_8888_scale_bilerp 61.9us -> 62.2us 1.01x > bitmap_RGBA_8888_update_volatile_scale_rotate_bilerp 102us -> 101us 0.99x > bitmap_RGBA_8888_scale_rotate_bilerp 103us -> 101us 0.99x > bitmap_RGBA_8888_scale 18.4us -> 18.2us 0.99x > bitmap_RGBA_8888_A_scale_rotate_bicubic 71us -> 70us 0.99x > bitmap_RGBA_8888_update_scale_rotate_bilerp 103us -> 101us 0.99x > bitmap_RGBA_8888_A_scale_rotate_bilerp 112us -> 109us 0.98x > bitmap_RGBA_8888_update_volatile 5.72us -> 5.58us 0.98x > bitmap_RGBA_8888 5.73us -> 5.58us 0.97x > bitmap_RGBA_8888_update 5.78us -> 5.6us 0.97x > bitmap_RGBA_8888_A_scale_bilerp 70.7us -> 68us 0.96x > bitmap_RGBA_8888_A_scale_bicubic 23.7us -> 21.8us 0.92x > bitmap_RGBA_8888_A 13.9us -> 10.9us 0.78x > bitmap_RGBA_8888_A_source_opaque 14us -> 6.29us 0.45x > bitmap_RGBA_8888_A_source_transparent 14us -> 3.65us 0.26x > > Running over our ~70 SKP web page captures, this looks like we spend 0.7x > the time in S32A_Opaque_BlitRow compared to the SSE2 version, which should > be a decent predictor of real-world impact. > > BUG=chromium:399842 > > Committed: https://skia.googlesource.com/skia/+/04bc91b972417038fecfa87c484771eac2b9b785 TBR=henrik.smiding@intel.com,mtklein@google.com,herb@google.com,reed@google.com,thakis@chromium.org,mtklein@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=chromium:399842 Review URL: https://codereview.chromium.org/874033004
Diffstat (limited to 'src/opts/SkBlitRow_opts_SSE4.cpp')
-rw-r--r--src/opts/SkBlitRow_opts_SSE4.cpp69
1 files changed, 0 insertions, 69 deletions
diff --git a/src/opts/SkBlitRow_opts_SSE4.cpp b/src/opts/SkBlitRow_opts_SSE4.cpp
deleted file mode 100644
index 6a6d7f834a..0000000000
--- a/src/opts/SkBlitRow_opts_SSE4.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "SkBlitRow_opts_SSE4.h"
-
-// Some compilers can't compile SSSE3 or SSE4 intrinsics. We give them stub methods.
-// The stubs should never be called, so we make them crash just to confirm that.
-#if SK_CPU_SSE_LEVEL < SK_CPU_SSE_LEVEL_SSE41
-void S32A_Opaque_BlitRow32_SSE4(SkPMColor* SK_RESTRICT, const SkPMColor* SK_RESTRICT, int, U8CPU) {
- sk_throw();
-}
-
-#else
-
-#ifdef _MSC_VER
- #include <intrin.h>
-#else
- #include <x86intrin.h>
-#endif
-
-#include "SkColorPriv.h"
-#include "SkColor_opts_SSE2.h"
-
-void S32A_Opaque_BlitRow32_SSE4(SkPMColor* SK_RESTRICT dst,
- const SkPMColor* SK_RESTRICT src,
- int count,
- U8CPU alpha) {
- SkASSERT(alpha == 255);
- // As long as we can, we'll work on 16 pixel pairs at once.
- int count16 = count / 16;
- __m128i* dst4 = (__m128i*)dst;
- const __m128i* src4 = (const __m128i*)src;
-
- for (int i = 0; i < count16 * 4; i += 4) {
- // Load 16 source pixels.
- __m128i s0 = _mm_loadu_si128(src4+i+0),
- s1 = _mm_loadu_si128(src4+i+1),
- s2 = _mm_loadu_si128(src4+i+2),
- s3 = _mm_loadu_si128(src4+i+3);
-
- const __m128i alphaMask = _mm_set1_epi32(0xFF << SK_A32_SHIFT);
- const __m128i ORed = _mm_or_si128(s3, _mm_or_si128(s2, _mm_or_si128(s1, s0)));
- if (_mm_testz_si128(ORed, alphaMask)) {
- // All 16 source pixels are fully transparent. There's nothing to do!
- continue;
- }
- const __m128i ANDed = _mm_and_si128(s3, _mm_and_si128(s2, _mm_and_si128(s1, s0)));
- if (_mm_testc_si128(ANDed, alphaMask)) {
- // All 16 source pixels are fully opaque. There's no need to read dst or blend it.
- _mm_storeu_si128(dst4+i+0, s0);
- _mm_storeu_si128(dst4+i+1, s1);
- _mm_storeu_si128(dst4+i+2, s2);
- _mm_storeu_si128(dst4+i+3, s3);
- continue;
- }
- // The general slow case: do the blend for all 16 pixels.
- _mm_storeu_si128(dst4+i+0, SkPMSrcOver_SSE2(s0, _mm_loadu_si128(dst4+i+0)));
- _mm_storeu_si128(dst4+i+1, SkPMSrcOver_SSE2(s1, _mm_loadu_si128(dst4+i+1)));
- _mm_storeu_si128(dst4+i+2, SkPMSrcOver_SSE2(s2, _mm_loadu_si128(dst4+i+2)));
- _mm_storeu_si128(dst4+i+3, SkPMSrcOver_SSE2(s3, _mm_loadu_si128(dst4+i+3)));
- }
-
- // Wrap up the last <= 15 pixels.
- for (int i = count16*16; i < count; i++) {
- // This check is not really necessarily, but it prevents pointless autovectorization.
- if (src[i] & 0xFF000000) {
- dst[i] = SkPMSrcOver(src[i], dst[i]);
- }
- }
-}
-
-#endif