Alpha blending dla Delphi w assemblerze z wykorzystaniem MMX:
function AlphaBlend(Pixel: dword; Background: dword; Alpha: byte): dword;
begin
asm
movzx eax,Alpha // kanal alfa 0-255
imul eax,01010101h // 000000xx = xx xx xx xx
movd mm6,eax //
pxor mm7,mm7 //
punpcklbw mm6,mm7 // rozpakuj do bajtow
mov edx,00FFFFFFh
movd mm2,edx
movd mm0,Background // pixel z tla
pand mm0,mm2 // usun kanal alfa z tla
movd mm1,Pixel // pixel obrazu
pand mm1,mm2 // usun kanal alfa z pixela
punpcklbw mm0,mm7 // rozpakuj pixel obrazu do bajtow
punpcklbw mm1,mm7 // oraz pixel litery do bajtow
psubw mm0,mm1 // src - pix
pmullw mm0,mm6 // *alpha
psrlw mm0,8 // >> 8
paddb mm0,mm1 // +
packuswb mm0,mm7 // spakuj ponownie do pixela
movd eax,mm0 // zapisz do eax
mov Result,eax
end;
end;
To tylko przykład, można to zoptymalizować pod względem konwencji regcall, ale już mi się nie chcę, z dedykacją dla jednego geniusza, który twierdził, że to niemożliwe…
Nie wierzę, że da się to zoptymalizować pod względem konwencji regcall… to niemożliwe 🙂
sam wiesz, że się da ;), trzeba samemu pierwsze 3 parametry przechwycić z EAX ECX i EDX i procke zadeklarować jako function Proc():dword;assembler; bo tak parametry sa odczytywane przez stos, zawsze to jakas optymalizacja hehe
W skrócie to prockę oznaczyć jako naked, a regcall widać znam pod nazwą fastcall :). Choć ja zawsze byłem wyznawcą dzielenia kodu na jakieś logiczne moduły, tj. tą prockę wyrzuciłbym do pliku .asm, a w projekcie hll zrobiłbym do niej kilka externów ;>.
zwał jak zwał, właśnie ten keyword assembler; oznacza ją jako naked (dla takich C++ geeków jak ty), jak taki miszcz jesteś to napisz to w SSE4 😛 hehe
Haha, widzę bart, że przez te wszystkie lata Twoje ortodoksyjne podejście do asm nie uległo najmniejszej zmianie 😀 Semper fidelis assembleris!
to akurat kod z jakiejś starej pracy, a że jest całkiem sprawny i akurat komuś pomógł to cieszy mnie to ogromnie ;), jeszcze ci pokaże co znaczy podejście do assembler hehe, padniesz 🙂