🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.delphi.basm
10 messages
10 total messages Started by Dennis Mon, 09 Sep 2002 19:38
Alpha Blend
#210
Author: Dennis
Date: Mon, 09 Sep 2002 19:38
189 lines
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
#215
Author: ADS
Date: Tue, 10 Sep 2002 07:07
12 lines
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
#217
Author: Dennis
Date: Tue, 10 Sep 2002 09:20
39 lines
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
#219
Author: ADS
Date: Tue, 10 Sep 2002 11:29
28 lines
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
#218
Author: ADS
Date: Tue, 10 Sep 2002 11:45
4 lines
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
#227
Author: Dennis
Date: Tue, 10 Sep 2002 16:04
29 lines
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
#229
Author: ADS
Date: Tue, 10 Sep 2002 16:31
16 lines
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
#232
Author: chris jones
Date: Tue, 10 Sep 2002 17:42
43 lines
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
#233
Author: chris jones
Date: Tue, 10 Sep 2002 17:46
16 lines
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
#234
Author: Torjei Kvinen
Date: Tue, 10 Sep 2002 20:53
24 lines
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