I tracked down the alpha blending bug I referred to in my previous email
to BlitRGBtoRGBPixelAlphaMMX3DNOW(), GCC_ASMBLIT version. The bug is in
the branch that actually blends two pixels :
__asm__ (
/* load in the source, and dst. /
“movd (%0), %%mm0\n” / mm0(s) = 0 0 0 0 | As Rs Gs Bs /
“movd (%1), %%mm1\n” / mm1(d) = 0 0 0 0 | Ad Rd Gd Bd */
/* Move the src alpha into mm2 */
/* if supporting pshufw /
/“pshufw $0x55, %%mm0, %%mm2\n” / / mm2 = 0 As 0 As | 0 As 0
As /
/“psrlw $8, %%mm2\n” */
/* else: */
“movd %2, %%mm2\n”
********** HERE IS THE BUG **********
//“psrld %%mm5, %%mm2\n” /* mm2 = 0 0 0 0 | 0 0 0 As /
“psrld $24, %%mm2\n” / mm2 = 0 0 0 0 | 0 0 0 As /************************************
“punpcklwd %%mm2, %%mm2\n” /* mm2 = 0 0 0 0 | 0 As 0 As /
“punpckldq %%mm2, %%mm2\n” / mm2 = 0 As 0 As | 0 As 0 As */
“pand %%mm7, %%mm2\n” /* to preserve dest alpha */
/* move the colors into words. /
“punpcklbw %%mm6, %%mm0\n” / mm0 = 0 As 0 Rs | 0 Gs 0 Bs /
“punpcklbw %%mm6, %%mm1\n” / mm0 = 0 Ad 0 Rd | 0 Gd 0 Bd */
/* src - dst /
“psubw %%mm1, %%mm0\n” / mm0 = As-Ad Rs-Rd | Gs-Gd Bs-Bd */
/* A * (src-dst) /
“pmullw %%mm2, %%mm0\n” / mm0 = 0As-d AsRs-d | AsGs-d AsBs-d /
“psrlw $8, %%mm0\n” / mm0 = 0>>8 Rc>>8 | Gc>>8 Bc>>8 /
“paddb %%mm1, %%mm0\n” / mm0 = 0+Ad Rc+Rd | Gc+Gd Bc+Bd */
“packuswb %%mm0, %%mm0\n” /* mm0 = | Ac Rc Gc Bc */
“movd %%mm0, (%1)\n” /* result in mm0 */
: : "r" (srcp), "r" (dstp), "r" (alpha) );
***** Right-shifting 24 bits there produces correct results for this
case where the alpha mask is indeed 0xFF000000. 24 is the value of
sf->Ashift which is loaded in mm5, however shifting by mm5 there
produces the bug - is it possible that mm5 is getting clobbered
somewhere?
This is my first approach to MMX so I really don’t know how to continue
with this. Can anyone (preferably the original author of this function
or a MMX guru) suggest anything?
Thanks,
–Gabriel
Gabriel Gambetta
Mystery Studio - http://www.mysterystudio.com
Gabriel on Graphics - http://gabrielongraphics.blogspot.com