mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
An extra 5-10% speedup for I4 texture decoding with SSE4.1 intrinsics.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6772 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
418357190b
commit
9cb3340754
@ -961,8 +961,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he
|
||||
// Produces a ~76% speed increase over reference C implementation.
|
||||
const __m128i kMask_x0f = _mm_set_epi32(0x0f0f0f0fL, 0x0f0f0f0fL, 0x0f0f0f0fL, 0x0f0f0f0fL);
|
||||
const __m128i kMask_xf0 = _mm_set_epi32(0xf0f0f0f0L, 0xf0f0f0f0L, 0xf0f0f0f0L, 0xf0f0f0f0L);
|
||||
const __m128i kMask_x00000000ffffffff = _mm_set_epi32(0x00000000L, 0xffffffffL, 0x00000000L, 0xffffffffL);
|
||||
const __m128i kMask_xffffffff00000000 = _mm_set_epi32(0xffffffffL, 0x00000000L, 0xffffffffL, 0x00000000L);
|
||||
|
||||
for (int y = 0; y < height; y += 8)
|
||||
for (int x = 0; x < width; x += 8)
|
||||
@ -1033,19 +1031,32 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he
|
||||
// (bbbbbbbb bbbbbbbb aaaaaaaa aaaaaaaa) -> (bbbbbbbb 00000000 aaaaaaaa 00000000)
|
||||
// And last but not least, _mm_or_si128 ORs those two together, giving us the interleaving we desire:
|
||||
// (00000000 BBBBBBBB 00000000 AAAAAAAA) | (bbbbbbbb 00000000 aaaaaaaa 00000000) -> (bbbbbbbb BBBBBBBB aaaaaaaa AAAAAAAA)
|
||||
const __m128i o1 = _mm_or_si128(_mm_and_si128(i151, kMask_x00000000ffffffff), _mm_and_si128(i251, kMask_xffffffff00000000));
|
||||
const __m128i o2 = _mm_or_si128(_mm_and_si128(i152, kMask_x00000000ffffffff), _mm_and_si128(i252, kMask_xffffffff00000000));
|
||||
#if _M_SSE >= 0x401
|
||||
// SSE4 gives 5-10% improvement in I4 texture decode when this runs:
|
||||
if (cpu_info.bSSE4_1) {
|
||||
const __m128i o1 = _mm_blend_epi16(i251, i151, 0x33); // 0x33 = 00110011
|
||||
const __m128i o2 = _mm_blend_epi16(i252, i152, 0x33);
|
||||
const __m128i o3 = _mm_blend_epi16(i261, i161, 0x33);
|
||||
const __m128i o4 = _mm_blend_epi16(i262, i162, 0x33);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
const __m128i kMask_x00000000ffffffff = _mm_set_epi32(0x00000000L, 0xffffffffL, 0x00000000L, 0xffffffffL);
|
||||
const __m128i kMask_xffffffff00000000 = _mm_set_epi32(0xffffffffL, 0x00000000L, 0xffffffffL, 0x00000000L);
|
||||
const __m128i o1 = _mm_or_si128(_mm_and_si128(i151, kMask_x00000000ffffffff), _mm_and_si128(i251, kMask_xffffffff00000000));
|
||||
const __m128i o2 = _mm_or_si128(_mm_and_si128(i152, kMask_x00000000ffffffff), _mm_and_si128(i252, kMask_xffffffff00000000));
|
||||
|
||||
// These two are for the next row; same pattern as above. We batched up two rows because our input was 64 bits.
|
||||
const __m128i o3 = _mm_or_si128(_mm_and_si128(i161, kMask_x00000000ffffffff), _mm_and_si128(i261, kMask_xffffffff00000000));
|
||||
const __m128i o4 = _mm_or_si128(_mm_and_si128(i162, kMask_x00000000ffffffff), _mm_and_si128(i262, kMask_xffffffff00000000));
|
||||
// These two are for the next row; same pattern as above. We batched up two rows because our input was 64 bits.
|
||||
const __m128i o3 = _mm_or_si128(_mm_and_si128(i161, kMask_x00000000ffffffff), _mm_and_si128(i261, kMask_xffffffff00000000));
|
||||
const __m128i o4 = _mm_or_si128(_mm_and_si128(i162, kMask_x00000000ffffffff), _mm_and_si128(i262, kMask_xffffffff00000000));
|
||||
|
||||
// Write row 0:
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy) * width + x ), o1 );
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy) * width + x + 4 ), o2 );
|
||||
// Write row 1:
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy+1) * width + x ), o3 );
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy+1) * width + x + 4 ), o4 );
|
||||
// Write row 0:
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy) * width + x ), o1 );
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy) * width + x + 4 ), o2 );
|
||||
// Write row 1:
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy+1) * width + x ), o3 );
|
||||
_mm_storeu_si128( (__m128i*)( dst+(y + iy+1) * width + x + 4 ), o4 );
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
// Reference C implementation:
|
||||
|
Loading…
Reference in New Issue
Block a user