Author Topic: Trying to optimise fadeout  (Read 1914 times)

0 Members and 1 Guest are viewing this topic.

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Trying to optimise fadeout
« on: July 18, 2008 »
Hi, I have a fadeout effect, but its too slow o my eeepc. I get 15fps :/ I have a fast version ,commented out, but it fades out too quickly. The bottleneck seems to be the floating point maths and the type casting. Heres the code:

Code: [Select]
void blit_and_fade(float mod)
{
int i, size = GRAPHICS_W*GRAPHICS_H;
Uint32 *pix = (Uint32*)screen->pixels;
Uint32 *buf = buffer;
Uint32 r_b, g;

for(i=0; i<size; i++, pix++, buf++)
{
*pix = *buf;
r_b = (Uint32)((*buf & 0x00FF00FF) * mod) & 0x00FF00FF;
g   = (Uint32)((*buf & 0x0000FF00) * mod) & 0x0000FF00;
*buf = r_b | g;
//*buf = (*buf >> 1) & 8355711; // <- FAST FADE LOOKS CRAP
}
}
Any suggestion how I coud do this w/o the floating point? Cheers.

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1289
  • Karma: 466
    • View Profile
    • my stuff
Re: Trying to optimise fadeout
« Reply #1 on: July 18, 2008 »
Straight forward:
Code: [Select]
void fade(uin32 *dst, uint32 *src, int size, float mod)
{
int f= mod * 256.0f;

for(int i=0; i<size; i++)
{
                uint32 col= src[i];
int r= (col>>16&255)*f>>8;
int g= (col>>8&255)*f>>8;
int b= (col&255)*f>>8;
        dst[i]= (r<<16)|(g<<8)|b;
}
}

More generally you just replace the float by a fraction of integers a/b and make "b" a power of two to remove the division.
« Last Edit: July 18, 2008 by hellfire »
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: Trying to optimise fadeout
« Reply #2 on: July 18, 2008 »
Oh yeah,  *256 was the wy to do it. Cheers dude I got > 100fps now :)

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1289
  • Karma: 466
    • View Profile
    • my stuff
Re: Trying to optimise fadeout
« Reply #3 on: July 18, 2008 »
another one (using mmx):
Code: [Select]
void fade(uint32 *dst, uint32 *src, int intense, int isize)
{
    _asm {
          mov       edi,dst        // dst-pointer
          mov       esi,src        // src-pointer
          mov       ecx,isize      // loop counter
          shl       ecx,2          // *4
          add       edi,ecx        // count backwards
          add       esi,ecx
          neg       ecx
          mov       eax,intense    // fade
          imul      eax,0x01010101 // to 8:8:8:8
          pxor      mm3,mm3        // 0
          movd      mm1,eax     
          punpcklbw mm1,mm3        // 8:8:8:8 to 16:16:16:16 (each upper byte 0)

   floop: movq      mm0,[esi+ecx]  // read two source pixels
          movq      mm4,mm0        // copy
          punpcklbw mm0,mm3        // pixel1: upper dword 8:8:8:8 to 16:16:16:16
          psrlq     mm4,32         // lower dword to upper dword
          pmullw    mm0,mm1        // pixel1 * intense
          psrlw     mm0,8          // pixel1 >>= 8
          punpcklbw mm4,mm3        // pixel2: 8:8:8:8 to 16:16:16:16   
          packuswb  mm0,mm3        // pixel1: 16:16:16:16 to 8:8:8:8
          pmullw    mm4,mm1        // pixel2 * intense
          psrlw     mm4,8          // pixel2 >>= 8
          packuswb  mm4,mm3        // pixel2: 16:16:16:16 to 8:8:8:8
          psllq     mm4,32         // pixel1 to upper dword
          paddw     mm4,mm0        // pixel2 to lower dword
          movq      [edi+ecx],mm4  // store two pixels
          add       ecx,8          // next pixel
          jnz       floop          // loop
          emms                 
    };
}
(not quite optimal, the source is 10 years old)
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: Trying to optimise fadeout
« Reply #4 on: July 18, 2008 »
Cool. I have wanted to learn how to use the MMX registers sometime. Its just something I  havent got around to doing. I'll come back to this later on ;)

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1307
  • Karma: 96
    • View Profile
Re: Trying to optimise fadeout
« Reply #5 on: July 19, 2008 »
To take it further you could do something like this:

Code: [Select]
col=src[i];
dst[i]=((((col&0xff00ff)*f)&0xff00ff00)|(((col&0xff00)*f)&0xff0000))>>8;

EDIT:oops, forgot a little bit of it but I think that's it now.
« Last Edit: July 19, 2008 by Stonemonkey »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Trying to optimise fadeout
« Reply #6 on: July 21, 2008 »
How about the programmer fade?  Again from Amiga days...
Code: [Select]
p = *pix
r =0xff&( p>>16)
g=0xff&(p>>8)
b=0xff&p;

r--
g--
b--

if r<0 r=0
if g<0 g=0
if b<0 b=0

*pix = (r<<16)|(g<<8)|b

Jim

<edit> I should pay attention - this is more for fading screens to black
Challenge Trophies Won: