comparison src/video/SDL_blit_N.c @ 1139:d0ae4dff7208

Altivec blitter for 555 -> 8888 surface, written by me. --ryan.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 08 Sep 2005 07:20:59 +0000
parents f596fa4f17a6
children 2651158f59b8
comparison
equal deleted inserted replaced
1138:fcfb783a3ca2 1139:d0ae4dff7208
348 vsrc = vec_perm(vsrc, voverflow, valigner); 348 vsrc = vec_perm(vsrc, voverflow, valigner);
349 349
350 vR = vec_and((vector unsigned short)vsrc, vf800); 350 vR = vec_and((vector unsigned short)vsrc, vf800);
351 vB = vec_sl((vector unsigned short)vsrc, v3); 351 vB = vec_sl((vector unsigned short)vsrc, v3);
352 vG = vec_sl(vB, v2); 352 vG = vec_sl(vB, v2);
353
354 vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha1);
355 vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1);
356 vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1);
357 vdst1 = vec_perm(vdst1, valpha, vpermute);
358 vec_st(vdst1, 0, dst);
359
360 vdst2 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha2);
361 vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2);
362 vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2);
363 vdst2 = vec_perm(vdst2, valpha, vpermute);
364 vec_st(vdst2, 16, dst);
365
366 width -= 8;
367 dst += 32;
368 src += 16;
369 vsrc = voverflow;
370 }
371
372 assert(width == 0);
373
374
375 /* do scalar until we can align... */
376 ONE_PIXEL_BLEND((extrawidth), extrawidth);
377 #undef ONE_PIXEL_BLEND
378
379 src += srcskip; /* move to next row, accounting for pitch. */
380 dst += dstskip;
381 }
382
383 }
384
385
386 static void Blit_RGB555_32Altivec(SDL_BlitInfo *info) {
387 int height = info->d_height;
388 Uint8 *src = (Uint8 *) info->s_pixels;
389 int srcskip = info->s_skip;
390 Uint8 *dst = (Uint8 *) info->d_pixels;
391 int dstskip = info->d_skip;
392 SDL_PixelFormat *srcfmt = info->src;
393 SDL_PixelFormat *dstfmt = info->dst;
394 unsigned alpha;
395 vector unsigned char valpha;
396 vector unsigned char vpermute;
397 vector unsigned short vf800;
398 vector unsigned int v8 = vec_splat_u32(8);
399 vector unsigned int v16 = vec_add(v8, v8);
400 vector unsigned short v1 = vec_splat_u16(1);
401 vector unsigned short v3 = vec_splat_u16(3);
402 /*
403 0x10 - 0x1f is the alpha
404 0x00 - 0x0e evens are the red
405 0x01 - 0x0f odds are zero
406 */
407 vector unsigned char vredalpha1 = (vector unsigned char)(
408 0x10, 0x00, 0x01, 0x01,
409 0x10, 0x02, 0x01, 0x01,
410 0x10, 0x04, 0x01, 0x01,
411 0x10, 0x06, 0x01, 0x01
412 );
413 vector unsigned char vredalpha2 = (vector unsigned char)(
414 vec_add((vector unsigned int)vredalpha1, vec_sl(v8, v16))
415 );
416 /*
417 0x00 - 0x0f is ARxx ARxx ARxx ARxx
418 0x11 - 0x0f odds are blue
419 */
420 vector unsigned char vblue1 = (vector unsigned char)(
421 0x00, 0x01, 0x02, 0x11,
422 0x04, 0x05, 0x06, 0x13,
423 0x08, 0x09, 0x0a, 0x15,
424 0x0c, 0x0d, 0x0e, 0x17
425 );
426 vector unsigned char vblue2 = (vector unsigned char)(
427 vec_add((vector unsigned int)vblue1, v8)
428 );
429 /*
430 0x00 - 0x0f is ARxB ARxB ARxB ARxB
431 0x10 - 0x0e evens are green
432 */
433 vector unsigned char vgreen1 = (vector unsigned char)(
434 0x00, 0x01, 0x10, 0x03,
435 0x04, 0x05, 0x12, 0x07,
436 0x08, 0x09, 0x14, 0x0b,
437 0x0c, 0x0d, 0x16, 0x0f
438 );
439 vector unsigned char vgreen2 = (vector unsigned char)(
440 vec_add((vector unsigned int)vgreen1, vec_sl(v8, v8))
441 );
442
443
444 assert(srcfmt->BytesPerPixel == 2);
445 assert(dstfmt->BytesPerPixel == 4);
446
447 vf800 = (vector unsigned short)vec_splat_u8(-7);
448 vf800 = vec_sl(vf800, vec_splat_u16(8));
449
450 if (dstfmt->Amask && srcfmt->alpha) {
451 ((unsigned char *)&valpha)[0] = alpha = srcfmt->alpha;
452 valpha = vec_splat(valpha, 0);
453 } else {
454 alpha = 0;
455 valpha = vec_splat_u8(0);
456 }
457
458 vpermute = calc_swizzle32(NULL, dstfmt);
459 while (height--) {
460 vector unsigned char valigner;
461 vector unsigned char voverflow;
462 vector unsigned char vsrc;
463
464 int width = info->d_width;
465 int extrawidth;
466
467 /* do scalar until we can align... */
468 #define ONE_PIXEL_BLEND(condition, widthvar) \
469 while (condition) { \
470 unsigned sR, sG, sB; \
471 unsigned short pixel = *((unsigned short *)src); \
472 sR = (pixel >> 7) & 0xf8; \
473 sG = (pixel >> 2) & 0xf8; \
474 sB = (pixel << 3) & 0xf8; \
475 ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
476 src += 2; \
477 dst += 4; \
478 widthvar--; \
479 }
480 ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
481
482 /* After all that work, here's the vector part! */
483 extrawidth = (width % 8); /* trailing unaligned stores */
484 width -= extrawidth;
485 vsrc = vec_ld(0, src);
486 valigner = VEC_ALIGNER(src);
487
488 while (width) {
489 vector unsigned short vR, vG, vB;
490 vector unsigned char vdst1, vdst2;
491
492 voverflow = vec_ld(15, src);
493 vsrc = vec_perm(vsrc, voverflow, valigner);
494
495 vR = vec_and(vec_sl((vector unsigned short)vsrc,v1), vf800);
496 vB = vec_sl((vector unsigned short)vsrc, v3);
497 vG = vec_sl(vB, v3);
353 498
354 vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha1); 499 vdst1 = (vector unsigned char)vec_perm((vector unsigned char)vR, valpha, vredalpha1);
355 vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1); 500 vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1);
356 vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1); 501 vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1);
357 vdst1 = vec_perm(vdst1, valpha, vpermute); 502 vdst1 = vec_perm(vdst1, valpha, vpermute);
2088 #endif 2233 #endif
2089 #ifdef USE_ALTIVEC_BLITTERS 2234 #ifdef USE_ALTIVEC_BLITTERS
2090 /* has-altivec */ 2235 /* has-altivec */
2091 { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00000000,0x00000000,0x00000000, 2236 { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00000000,0x00000000,0x00000000,
2092 2, NULL, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, 2237 2, NULL, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
2238 { 0x00007C00,0x000003E0,0x0000001F, 4, 0x00000000,0x00000000,0x00000000,
2239 2, NULL, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA },
2093 #endif 2240 #endif
2094 { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF, 2241 { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF,
2095 0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA }, 2242 0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA },
2096 { 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000, 2243 { 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000,
2097 0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA }, 2244 0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA },