Thread View: borland.public.delphi.basm
10 messages
10 total messages
Started by Dennis
Mon, 09 Sep 2002 19:38
Alpha Blend
Author: Dennis
Date: Mon, 09 Sep 2002 19:38
Date: Mon, 09 Sep 2002 19:38
189 lines
5800 bytes
5800 bytes
Hi All I know we have looked on the Alpha Blend function not long ago. Can we take a round on it again? I think it will bring forward some interesting issues of general importance. This is my basic Pascal implementation. function BlendDKCI1(const Source1, Source2 : TColor; AlphaInt : Byte) : TColor; begin Result[1] := Source2[1] - ((Source2[1] - Source1[1]) * AlphaInt) shr 8 ; Result[2] := Source2[2] - ((Source2[2] - Source1[2]) * AlphaInt) shr 8; Result[3] := Source2[3] - ((Source2[3] - Source1[3]) * AlphaInt) shr 8; end; type TColor = array[1..3] of byte; I have done some optimization on it, and this is the fastest Pascal implementation i could make function BlendDKCI4(var Source1, Source2 : TColor; const AlphaInt : Byte) : TColor; begin Result[1] := Source2[1] - ((Source2[1] - Source1[1]) * AlphaInt) shr 8 ; Result[2] := Source2[2] - ((Source2[2] - Source1[2]) * AlphaInt) shr 8; Result[3] := Source2[3] - ((Source2[3] - Source1[3]) * AlphaInt) shr 8; end; This is my best MMX implementation function BlendDKCMMX4(var Source1, Source2 : TColor2; var AlphaInt : Byte) : TColor2; asm //Load data MOVD MM0, [EDX] MOVD MM1, [EAX] MOVD MM2, [ECX] //Broadcast AlphaInt PUNPCKLBW MM2, MM2 PUNPCKLBW MM2, MM2 PXOR MM6, MM6 PUNPCKLBW MM6, MM2 PSRLQ MM6, 8 //Widen format of input data PUNPCKLBW MM3, MM0 PSRLW MM3, 8 PUNPCKLBW MM4, MM1 PSRLW MM4, 8 //Temp10 := (255 - Alpha); PXOR MM5, MM5 PCMPEQB MM5, MM5 PSUBW MM5, MM6 PSLLW MM5, 8 PSRLW MM5, 8 //Temp1 := Source1 * Alpha; PMULLW MM4, MM6 //Temp2 := Source2 * Temp10; PMULLW MM3, MM5 //Temp3 := Temp1 + Temp2; PADDW MM4, MM3 //Result := Temp3 shr 8; PSRLW MM4, 8 //Pack result into bytes PACKUSWB MM7, MM4 PSLLQ MM7, 8 PSRLQ MM7, 8 PSRLQ MM7, 32 //Deliver Result in EAX MOVD [ESP - $04], MM7 MOV EAX, [ESP - $04] EMMS end; This is my best SSE implementation function BlendSSEI2(var Source1, Source2 : TColor2; var AlphaInt : Byte) : TColor2; asm //Load data MOVD MM0, [EDX] MOVD MM1, [EAX] MOVD MM2, [ECX] //Temp10 := (255 - Alpha); PXOR MM3, MM3 PCMPEQB MM3, MM3 //Create 255 PSUBB MM3, MM2 //(255 - Alpha); //Broadcast Alpha PSLLW MM2, 8 PSRLW MM2, 8 PSHUFW MM4, MM2, 0 //Broadcast 255 - Alpha PSLLW MM3, 8 PSRLW MM3, 8 PSHUFW MM5, MM3, 0 //Widen format of input data PUNPCKLBW MM6, MM0 PSRLW MM6, 8 PUNPCKLBW MM7, MM1 PSRLW MM7, 8 //Temp1 := Source1 * Alpha; PMULLW MM7, MM4 //Temp2 := Source2 * Temp10; PMULLW MM6, MM5 //Temp3 := Temp1 + Temp2; PADDW MM7, MM6 //Result := Temp3 shr 8; PSRLW MM7, 8 //Pack result into bytes PACKUSWB MM7, MM7 PSLLQ MM7, 8 PSRLQ MM7, 8 PSRLQ MM7, 32 //Deliver Result in EAX MOVD [ESP - $04], MM7 MOV EAX, [ESP - $04] EMMS end; This is my best SSE2 implementation function BlendSSE2I1(var Source1, Source2 : TColor2; var Alpha : Byte) : TColor2; asm //Load data MOVD XMM0, [EAX] //Load Source1 MOVD XMM1, [EDX] //Load Source2 MOVD XMM2, [ECX] //Load Alpha //Widen format of input data PXOR XMM6, XMM6 PUNPCKLBW XMM6, XMM0 //Source1 in XMM6 PXOR XMM7, XMM7 PUNPCKLBW XMM7, XMM1 //Source2 in XMM7 PXOR XMM0, XMM0 PUNPCKLBW XMM0, XMM2 //Alpha in XMM0 //Broadcast Alpha PXOR XMM4, XMM4 PSHUFLW XMM4, XMM0, $0 //Alpha in XMM4 //Temp10 := (255 - Alpha); PXOR XMM5, XMM5 PCMPEQB XMM5, XMM5 //255 in XMM5 PSUBW XMM5, XMM4 //Temp10 in XMM5 PSRLW XMM5, 8 PSLLW XMM5, 8 //Temp1 := Source1 * Alpha; PMULHUW XMM6, XMM4 //Temp1 in XMM6 //Temp2 := Source2 * Temp10; PMULHUW XMM7, XMM5 //Temp3 := Temp1 + Temp2; //Temp2 in XMM7 PADDW XMM7, XMM6 //Temp3 in XMM7 //Result := Temp3 shr 8; PSRLW XMM7, 8 //Result in XMM7 //Pack result into bytes PACKUSWB XMM7, XMM7 //Deliver Result in EAX MOVD [ESP - $04], XMM7 MOV EAX, [ESP - $04] end; Timing results in clockcycles on P4 1600A I1 = 119, I4 = 42, MMX4 = 37, SSEI1 = 34, SSE2I1 = 26 Timing results in clockcycles on Celeron 1200 Tualatin I1 = 68, I4 = 35, MMX4 = 27, SSEI1 = 27, SSE2I1 = not supported Timing results in clockcycles on Pentium Pro 200 256 kB L2 I1 = 69, I4 = 37, MMX4 = not supported, SSEI1 = not supported, SSE2I1 = not supported Do any of you have some faster versions? Can anyone beat the compiler with IA32 integer based code? Is the preferred way of loading bytes XOR EAX, EAX + MOV AL, [EDX] versus MOVZX EAX, [EDX]? Can anyone provide timing results on Athlon XP? Dennis
Re: Alpha Blend
Author: ADS
Date: Tue, 10 Sep 2002 07:07
Date: Tue, 10 Sep 2002 07:07
12 lines
1234 bytes
1234 bytes
Dennis, I suppose that this works only with with 24 bits picture. won't it be faster to work on 32 bits picture (each color has it's alpha value)? maybe you can have a look at Graphics32 (it supports only MMX, not SSE or SSE2). Armindo
Re: Alpha Blend
Author: Dennis
Date: Tue, 10 Sep 2002 09:20
Date: Tue, 10 Sep 2002 09:20
39 lines
1595 bytes
1595 bytes
Hi ADS ADS wrote: > Dennis, > > I suppose that this works only with with 24 bits picture. > Yes my functions are tied together with the datatypes. > > won't it be faster to work on 32 bits picture (each color has it's alpha > value)? > Like this? TColor2 = array[1..4] of byte; If think not, but i will try it out. Both pixels one wants to blend has an alpha value - which one should we use ? (if they differ) > > maybe you can have a look at Graphics32 (it supports only MMX, not SSE or > SSE2). What is Graphics32? - it sounds interesting. > > > Armindo Dennis
Re: Alpha Blend
Author: ADS
Date: Tue, 10 Sep 2002 11:29
Date: Tue, 10 Sep 2002 11:29
28 lines
1545 bytes
1545 bytes
> Like this? > > TColor2 = array[1..4] of byte; yes > If think not, but i will try it out. > > Both pixels one wants to blend has an alpha value - which one should we use ? > (if they differ) Source one. > > maybe you can have a look at Graphics32 (it supports only MMX, not SSE or > > SSE2). > > What is Graphics32? - it sounds interesting. Hum hum, it's a great library made by Alex Denisov. is MMX alpha Blending works well so let me know if your SSE or SSE2 works faster. http://www.g32.org Armindo
Re: Alpha Blend
Author: ADS
Date: Tue, 10 Sep 2002 11:45
Date: Tue, 10 Sep 2002 11:45
4 lines
1094 bytes
1094 bytes
You can also look at http://esibert.developpez.com/delphi/mmx2/image.zip to see an example that show filters on 32 bits bitmap. Armindo
Re: Alpha Blend
Author: Dennis
Date: Tue, 10 Sep 2002 16:04
Date: Tue, 10 Sep 2002 16:04
29 lines
2018 bytes
2018 bytes
ADS wrote: > Dennis, > > I suppose that this works only with with 24 bits picture. > > won't it be faster to work on 32 bits picture (each color has it's alpha > value)? > If one has an application with the ability of blending two pictures i guess the user would fill in some Alpha value. This value is bound to the action of blending two pictures and not to the pictures themselves - i think. Therefore it is logical to me to not put Alpha values into pictures. If the user starts this application, loads two pictures, chose Alpha=x and starts blending, we would have to iterate through one or both pictures and fill in Alpha values and then start the blending process. We could also merge the two processes. Now we are copying a lot of data and this is only a good thing if we are about to repeat the blending process with the same alpha values. But it seems like 32 bit pictures with (Alpha values) are a normal thing. Which benefits do we have from this? > > maybe you can have a look at Graphics32 (it supports only MMX, not SSE or > SSE2). > > Armindo
Re: Alpha Blend
Author: ADS
Date: Tue, 10 Sep 2002 16:31
Date: Tue, 10 Sep 2002 16:31
16 lines
1494 bytes
1494 bytes
> But it seems like 32 bit pictures with (Alpha values) are a normal thing. > Which benefits do we have from this? The main advantage is that you have a specific alpha value for each pixel (interesting for making sprites or alphablending a specific region of the source bitmap. the other advantages is that you directly works with a DWord or an integer, in MMX it's more interesting to work in 8 bits, 16 bits or 32 bits. the other thing if you plan to port to kylix, it works on 8, 16 and 32 bitys not 24.... Armindo
Re: Alpha Blend
Author: chris jones
Date: Tue, 10 Sep 2002 17:42
Date: Tue, 10 Sep 2002 17:42
43 lines
2623 bytes
2623 bytes
"Dennis" <marianndennis@email.dk> wrote in message news:3D7E1807.24A08941@email.dk... > > > ADS wrote: > > > Dennis, > > > > I suppose that this works only with with 24 bits picture. > > > > won't it be faster to work on 32 bits picture (each color has it's alpha > > value)? > > > > If one has an application with the ability of blending two pictures i guess > the user would fill in some Alpha value. This value is bound to the action of > blending two pictures and not to the pictures themselves - i think. Therefore > it is logical to me to not put Alpha values into pictures. If the user starts > this application, loads two pictures, chose Alpha=x and starts blending, we > would have to iterate through one or both pictures and fill in Alpha values > and then start the blending process. We could also merge the two processes. > Now we are copying a lot of data and this is only a good thing if we are > about to repeat the blending process with the same alpha values. > But it seems like 32 bit pictures with (Alpha values) are a normal thing. > Which benefits do we have from this? Alpha values in bitmaps are used mostly for compositing pictures, basicly it alows antialiasing of the edges so where you have a round button the edges of the button will blend with the background so as to provide a smooth edge. Most comon is the pre-multiplied alpha type alpha channel where the alpha value is how much background to add, so if for example in a 3d rendering package a pixel is only half covered by the rendered object that pixel would end up with an alpha 128. Which basicly means this pixel is half forground and half background. chris
Re: Alpha Blend
Author: chris jones
Date: Tue, 10 Sep 2002 17:46
Date: Tue, 10 Sep 2002 17:46
16 lines
1476 bytes
1476 bytes
"chris jones" <flak@clara.co.uk> wrote in message news:3d7e2f03$1@newsgroups.borland.com... > // load and unpack the alpha (16 bit alpha) or insert 'psllq mm2,8;' for 8 > bit alpha > movd mm2,alpha; > punpcklwd mm2,mm2; > punpckldq mm2,mm2; line wrap messed it up a bit :) // load and unpack the alpha (16 bit alpha) or insert 'psllq mm2,8;' for // 8 bit alpha movd mm2,alpha; punpcklwd mm2,mm2; punpckldq mm2,mm2;
Re: Alpha Blend
Author: Torjei Kvinen
Date: Tue, 10 Sep 2002 20:53
Date: Tue, 10 Sep 2002 20:53
24 lines
1490 bytes
1490 bytes
"Dennis" <marianndennis@email.dk> wrote in message
> This is my basic Pascal implementation.
>
> function BlendDKCI1(const Source1, Source2 : TColor; AlphaInt : Byte) :
> TColor;
Is it possible to blend several pixels (the whole bitmap) with something
like this:
procedure Blend(Src1, Src2, Dst : PByteArray; Num, Alpha : Integer);
var
i : Integer;
begin
for i := 0 to Num-1 do
Dst[i] := Src2[i] - ((Src2[i] - Src1[i]) * Alpha) shr 8;
end;
If it's possible, I can imagine a very efficient code using SSE2.
--
Regards
Torjei Kvinen
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads