Mercurial > sdl-ios-xcode
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 }, |