Skip to content

Instantly share code, notes, and snippets.

@NewbiZ
Last active December 10, 2021 20:46
Show Gist options
  • Save NewbiZ/5541524 to your computer and use it in GitHub Desktop.
Save NewbiZ/5541524 to your computer and use it in GitHub Desktop.
Just a snippet to swap red and blue in a BGRA buffer, to get a RGBA buffer (useful when loading TGA).
#ifdef __SSSE3__
# include <xmmintrin.h>
# include <tmmintrin.h>
#endif
posix_memalign((void**)&pixels, 16, sizeof(unsigned int)*PIXEL_COUNT);
/*
* Mind this will only work for width * height % 16 == 0 textures
*/
void swap_pixels(unsigned int* pixels)
{
#ifdef __SSSE3__
// Shuffling mask (RGBA -> BGRA) x 4, in reverse byte order
static const __m128i m = _mm_set_epi8(15,12,13,14,11,8,9,10,7,4,5,6,3,0,1,2);
// Assert pixels will NOT be aliased here
__m128i* __restrict__ pix = (__m128i*)pixels;
// Tile the LHS to match 64B cache line size
for (; (unsigned int*)pix<pixels+PIXEL_COUNT; pix+=4)
{
__m128i p1 = _mm_load_si128(pix);
__m128i p2 = _mm_load_si128(pix+1);
__m128i p3 = _mm_load_si128(pix+2);
__m128i p4 = _mm_load_si128(pix+3);
p1 = _mm_shuffle_epi8(p1, m);
p2 = _mm_shuffle_epi8(p2, m);
p3 = _mm_shuffle_epi8(p3, m);
p4 = _mm_shuffle_epi8(p4, m);
_mm_store_si128(pix, p1);
_mm_store_si128(pix+1, p2);
_mm_store_si128(pix+2, p3);
_mm_store_si128(pix+3, p4);
}
#else
for (int i=0; i<PIXEL_COUNT; ++i)
{
char* p = (char*)(pixels+i);
char tmp = p[0];
p[0] = p[2];
p[2] = tmp;
}
#endif
}
free(pixels);
@vtorri
Copy link

vtorri commented Dec 10, 2021

compiler error : static const __m128i m = _mm_set_epi8(15,12,13,14,11,8,9,10,7,4,5,6,3,0,1,2); <--- not const

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment