Sto implementando una funzione di conversione veloce x888 -> 565 pixel in pixman in base all'algoritmo descritto by Intel [pdf]. Il loro codice converte x888 -> 555 mentre voglio convertire in 565. Sfortunatamente, la conversione in 565 significa che il bit più alto è impostato, il che significa che non posso usare le istruzioni del pacchetto di saturazione firmata. L'istruzione pack senza firma, packusdw non è stata aggiunta fino a SSE4.1. Mi piacerebbe implementare la sua funzionalità con SSE2 o trovare un altro modo per farlo.Simulazione della funzionalità packusdw con SSE2
Questa funzione richiede due registri XMM contenenti 4 pixel a 32 bit ciascuno e genera un singolo registro XMM contenente gli 8 pixel RGB565 convertiti.
static force_inline __m128i
pack_565_2packedx128_128 (__m128i lo, __m128i hi)
{
__m128i rb0 = _mm_and_si128 (lo, mask_565_rb);
__m128i rb1 = _mm_and_si128 (hi, mask_565_rb);
__m128i t0 = _mm_madd_epi16 (rb0, mask_565_pack_multiplier);
__m128i t1 = _mm_madd_epi16 (rb1, mask_565_pack_multiplier);
__m128i g0 = _mm_and_si128 (lo, mask_green);
__m128i g1 = _mm_and_si128 (hi, mask_green);
t0 = _mm_or_si128 (t0, g0);
t1 = _mm_or_si128 (t1, g1);
t0 = _mm_srli_epi32 (t0, 5);
t1 = _mm_srli_epi32 (t1, 5);
/* XXX: maybe there's a way to do this relatively efficiently with SSE2? */
return _mm_packus_epi32 (t0, t1);
}
idee che ho pensato di:
Sottraendo 0x8000, _mm_packs_epi32, ri-aggiungendo 0x8000 ad ogni 565 pixel. Ho provato questo, ma non posso farlo funzionare.
t0 = _mm_sub_epi16 (t0, mask_8000); t1 = _mm_sub_epi16 (t1, mask_8000); t0 = _mm_packs_epi32 (t0, t1); return _mm_add_epi16 (t0, mask_8000);
Mischiare i dati invece di imballarli. Funziona per MMX, ma dal momento che gli shuffles SSE a 16 bit funzionano solo sui 64 bit alti o bassi, sarebbe un po 'complicato.
Salvare i bit alti, impostarli su zero, eseguire il pacchetto, ripristinarli in seguito. Sembra abbastanza disordinato.
C'è qualche altro modo (spero più efficiente) di farlo?
Perfetto! Molte grazie. Dubito che possa essere fatto in modo più efficiente. – mattst88