@@ -65,38 +65,29 @@ void ConvertBGRA8888ToRGB888(u8 *dst, const u32 *src, u32 numPixels) {
6565}
6666
6767#if PPSSPP_ARCH(SSE2)
68- /*
69- #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
70- [[gnu::target("sse4.1")]]
71- #endif
72- */
68+ // fp64's improved version, see #19751
7369static inline void ConvertRGBA8888ToRGBA5551 (__m128i *dstp, const __m128i *srcp, u32 sseChunks) {
74- const __m128i maskAG = _mm_set1_epi32 (0x8000F800 );
7570 const __m128i maskRB = _mm_set1_epi32 (0x00F800F8 );
76- const __m128i mask = _mm_set1_epi32 (0x0000FFFF );
71+ const __m128i maskGA = _mm_set1_epi32 (0x8000F800 );
72+ const __m128i mulRB = _mm_set1_epi32 (0x04000001 );
73+ const __m128i mulGA = _mm_set1_epi32 (0x00400001 );
7774
7875 for (u32 i = 0 ; i < sseChunks; i += 2 ) {
79- __m128i c1 = _mm_load_si128 (&srcp[i + 0 ]);
80- __m128i c2 = _mm_load_si128 (&srcp[i + 1 ]);
81- __m128i ag, rb;
82-
83- ag = _mm_and_si128 (c1, maskAG);
84- ag = _mm_or_si128 (_mm_srli_epi32 (ag, 16 ), _mm_srli_epi32 (ag, 6 ));
85- rb = _mm_and_si128 (c1, maskRB);
86- rb = _mm_or_si128 (_mm_srli_epi32 (rb, 3 ), _mm_srli_epi32 (rb, 9 ));
87- c1 = _mm_and_si128 (_mm_or_si128 (ag, rb), mask);
88-
89- ag = _mm_and_si128 (c2, maskAG);
90- ag = _mm_or_si128 (_mm_srli_epi32 (ag, 16 ), _mm_srli_epi32 (ag, 6 ));
91- rb = _mm_and_si128 (c2, maskRB);
92- rb = _mm_or_si128 (_mm_srli_epi32 (rb, 3 ), _mm_srli_epi32 (rb, 9 ));
93- c2 = _mm_and_si128 (_mm_or_si128 (ag, rb), mask);
94-
95- #if 0
96- _mm_store_si128(&dstp[i / 2], _mm_packus_epi32(c1, c2));
97- #else
98- _mm_store_si128 (&dstp[i / 2 ], _mm_packu2_epi32_SSE2 (c1, c2));
99- #endif
76+ __m128i c0 = _mm_load_si128 (&srcp[i + 0 ]);
77+ __m128i c1 = _mm_load_si128 (&srcp[i + 1 ]);
78+
79+ __m128i rb0 = _mm_and_si128 (c0, maskRB); // 00000000bbbbb00000000000rrrrr000
80+ __m128i rb1 = _mm_and_si128 (c1, maskRB); // 00000000bbbbb00000000000rrrrr000
81+ __m128i ga0 = _mm_and_si128 (c0, maskGA); // a000000000000000ggggg00000000000
82+ __m128i ga1 = _mm_and_si128 (c1, maskGA); // a000000000000000ggggg00000000000
83+ rb0 = _mm_madd_epi16 (_mm_srli_epi32 (rb0, 3 ), mulRB); // 00000000000000000bbbbb00000rrrrr
84+ rb1 = _mm_madd_epi16 (_mm_srli_epi32 (rb1, 3 ), mulRB); // 00000000000000000bbbbb00000rrrrr
85+ ga0 = _mm_madd_epi16 (_mm_srli_epi32 (ga0, 11 ), mulGA); // 000000000000000000000a00000ggggg
86+ ga1 = _mm_madd_epi16 (_mm_srli_epi32 (ga1, 11 ), mulGA); // 000000000000000000000a00000ggggg
87+ __m128i rb = _mm_packs_epi32 (rb0, rb1);
88+ __m128i ga = _mm_slli_epi32 (_mm_packs_epi32 (ga0, ga1), 5 );
89+
90+ _mm_store_si128 (&dstp[i / 2 ], _mm_or_si128 (ga, rb));
10091 }
10192}
10293#endif
0 commit comments