SIMD Convert. sse4 version (still 1.4x faster than previous avx2 implementation)

This commit is contained in:
Alexander 2017-01-23 16:25:05 +03:00 committed by Alexander Karpinsky
parent d82fe3dd74
commit 03c150d0a6

View File

@ -593,6 +593,44 @@ rgba2rgbA(UINT8* out, const UINT8* in, int xsize)
#endif #endif
for (; x < xsize - 3; x += 4) {
__m128 mmaf;
__m128i pix0, pix1, pix2, pix3, mma;
__m128 mma0, mma1, mma2, mma3;
__m128 half = _mm_set1_ps(0.5);
__m128i source = _mm_loadu_si128((__m128i *) &in[x * 4]);
mma = _mm_and_si128(source, _mm_set_epi8(
0xff,0,0,0, 0xff,0,0,0, 0xff,0,0,0, 0xff,0,0,0));
mmaf = _mm_cvtepi32_ps(_mm_srli_epi32(source, 24));
mmaf = _mm_mul_ps(_mm_set1_ps(255), _mm_rcp_ps(mmaf));
mma0 = _mm_shuffle_ps(mmaf, mmaf, 0x00);
mma1 = _mm_shuffle_ps(mmaf, mmaf, 0x55);
mma2 = _mm_shuffle_ps(mmaf, mmaf, 0xaa);
mma3 = _mm_shuffle_ps(mmaf, mmaf, 0xff);
pix1 = _mm_unpacklo_epi8(source, _mm_setzero_si128());
pix3 = _mm_unpackhi_epi8(source, _mm_setzero_si128());
pix0 = _mm_unpacklo_epi16(pix1, _mm_setzero_si128());
pix1 = _mm_unpackhi_epi16(pix1, _mm_setzero_si128());
pix2 = _mm_unpacklo_epi16(pix3, _mm_setzero_si128());
pix3 = _mm_unpackhi_epi16(pix3, _mm_setzero_si128());
pix0 = _mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(pix0), mma0), half));
pix1 = _mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(pix1), mma1), half));
pix2 = _mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(pix2), mma2), half));
pix3 = _mm_cvtps_epi32(_mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(pix3), mma3), half));
pix0 = _mm_packus_epi32(pix0, pix1);
pix2 = _mm_packus_epi32(pix2, pix3);
source = _mm_packus_epi16(pix0, pix2);
source = _mm_blendv_epi8(source, mma, _mm_set_epi8(
0xff,0,0,0, 0xff,0,0,0, 0xff,0,0,0, 0xff,0,0,0));
_mm_storeu_si128((__m128i *) &out[x * 4], source);
}
in = &in[x * 4]; in = &in[x * 4];
out = &out[x * 4]; out = &out[x * 4];