Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

biskit

Optimizing my blitter

This topic is 6411 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have written my own blitter for my library, and am trying to optimize it. I have rewritten it a couple times, and it has improved, but now I am hoping to get some outside input on how to optimize it even further. The only thing i don''t want to here, is to re-write in asm. After I can get it optimized a little further in C, I will use the inline assembler and do so. All help will be very much appreciated. <table border=1 bgcolor=#FFFFFF cellpadding=0 cellspacing=0> <tr> <td>int CSurface::HandDrawSurface(CSurface *destSurface, int x, int y)
{
DWORD *pSrc, *pDest;
long srcPitch, destPitch;
RECT src;

if (!destSurface) return NULL;

x = x>>1; // divide by two
y = y>>1;

src.left = src.top = 0;
src.right = GetSurfaceWidth()>>1; src.bottom = GetSurfaceHeight();

LockSurface();
dest->LockSurface();

pSrc = (DWORD*)GetSurfacePtr();
pDest = (DWORD*)destSurface->GetSurfacPtr();
srcPitch = (DWORD)GetSurfacePitch()>>2;
destPitch = (DWORD)destSurface->GetSurfacePitch()>>2;

pDest += (y*destPitch) + x;

for (int y1=0;y1<src.bottom;y1++)

for (int x1=0;x1<src.right;x1++)
{
*pDest = *pSrc;

pSrc++;
pDest++;
}


destSurface->UnlockSurface();
UnlockSurface();

return TRUE;
}
</td> </tr> </table> ----------------------------------------

Share this post


Link to post
Share on other sites
Advertisement
Just glancing at your code I would recommend taking out the lock and unlock surface calls and do it manually each time you blt.

For instance, if you are blt''ing 100 tiles to the backbuffer you are locking and unlocking your backbuffer 100 times, resulting in 198 needless lock/unlock calls just on your backbuffer.


- Houdini

Share this post


Link to post
Share on other sites
Does this code actually work, all of the time...say if you''ve got x or y not equal to 0...why are you dividing them by 2 ? I can''t see how this helps unless you''re using a coordinate system that is exactly twice that of the screen coordinates, or you''re using 4 bit colour, ie 2 pixels per byte

Damn, I see where you''re going...are you having trouble adding a number of bytes to your DWORD pointer & it''s adding to much ? try this:

   pDest=(DWORD*)((DWORD)pDest+(y*destPitch)+x); 


I think that to calculate the x offset you should find out the number of bytes per pixel on the surface. Assuming that you''ve got this in the variable destBytesPP (note _bytes_), calculate pDest like this

   pDest=(DWORD*)((DWORD)pDest+(y*destPitch)+(x*destBytesPP)); 


next, what do src.left & src.top do for you...you set them to zero then proceed to ignore them there after...you might as well delete these statements.

next problem...you''ve calculated these pitches for the surfaces, but you don''t use these to advance the pointers after every line - usually you can get away with this, but not always - you should calculate how far the pointers need to be advanced to the begining of the next line...you may also have problems if the source surface is smaller than the destination surface... you could end up with the src blitted onto a line accross the dest rather than as a rectangle in the middle of the dest. One way to do this would be to have 2 extra pointers that get the value of the surface pointers at the begining of each row, then at the end of the row, make the surface pointers equal the the row begining pointer plus the pitch for the surface.

Try this code for the main loop

  
// declaration of new variables

DWORD *pSrcRowStart, *pDestRowStart;

// revised code for main loop

for (int y1=0;y1<src.bottom;y1++)
{
// save the pointer to the begining of the rows

pSrcRowStart=pSrc;
pDestRowStart=pDest;

for (int x1=0;x1<src.right;x1++)
{
*pDest = *pSrc;

pSrc++;
pDest++;
}

// set the pDest and pSrc pointers to the start of the next rows

pDest = (DWORD*)((DWORD)pSrcRowStart+srcPitch);
pSrc = (DWORD*)((DWORD)pDestRowStart+destPitch);
}


After that, one way of improving the through put will be to use MMX stuff, where you can do 8 bytes at a time (or more by unrolling loops)... you can do this by intrinsics, but I''m not sure how efficient these are, so you may have to use inline assembly. Houdini is right, you should find a way of minimising the use of lock/unlock on your surfaces if you can for more speed.

Hope you can find something useful here

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!