Jump to content
  • Advertisement
Sign in to follow this  
Flash2005

DirectDraw vs. GDI: GDI-Speedup after DDRelease ?!

This topic is 4753 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

Hi, at the moment I have to write a little benchmarkprogram using Visual C++ 6. The task is to show the "evolution" from GDI -> DirectDraw -> DirectGraphics. For this reason I programmed a simple test program in a Form (no MFC): 2 Bitmaps (256x256@8bit) with transparent areas 1 Bitmap (1x1@8bit) which is stretched on the background Now the test is always the same: 1. GetTickCount() 2. Start loop 3. Draw Background 4. Move the 2 sprites (one from upperleft to lower right and the other lower right to upper left) 5. As the 2 Sprites are crossing each other, the transparency is visible 6. Flip the Surfaces 6. loop 7. GetTickCount again to measure the elapsed time The GDI-Test has been done with the StretchBlt and Blt functions (Masking the DC to get transperancy and so on) In the DirectDraw-Test I only used the FastBlt function. Each test can be started by clicking a button. In the DirectDraw-case the DirectDraw gets initialized as you know it:
bool ddInit (HWND hwnd)
{
	ddrval = DirectDrawCreateEx(NULL, (VOID**)&lpDirectDraw, IID_IDirectDraw7, NULL); 
	if (ddrval != DD_OK)
	{
		return (0);
	}    

	ddrval = lpDirectDraw->SetCooperativeLevel (hwnd, DDSCL_EXCLUSIVE |	DDSCL_FULLSCREEN);
	if (ddrval != DD_OK)
	{
		ddRelease ();
		return (0);
	}

	ddrval = lpDirectDraw->SetDisplayMode (800, 600, 16, 0, 0);
	if (ddrval != DD_OK)
	{
		ddRelease ();
		return (0);
	}

	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
	ddsd.dwBackBufferCount = 1; 
	ddrval = lpDirectDraw->CreateSurface (&ddsd, &lpddsPrimary, NULL);
	if (ddrval != DD_OK)
	{
		ddRelease ();
		return (0);
	}
	ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
	lpddsPrimary->GetAttachedSurface(&ddscaps, &lpddsBack); 
        return true;
}
And the Release-Function at the end of the bench:
void ddRelease ()
{
	if (lpddsBack != NULL)
	{
		lpddsBack->Release();
		lpddsBack = NULL;
	} 
	if (lpddsPrimary != NULL)
	{
		lpddsPrimary->Release();
		lpddsPrimary = NULL;
	}
	if (lpDirectDraw != NULL)
	{
		lpDirectDraw->Release();
		lpDirectDraw = NULL;
	}
}
After the DirectDraw-Test the program returns from fullscreen back to the desktop-view with the programform and everything works fine. But now something is going strange: If I run the GDI-Test it always needs approx. 6 seconds to finish. And I can repeat this as often as I want .. its always near to the 6 seconds. But if I do the DirectDraw-Test and after that start the GDI-Test again it is much more faster! Now it only need approx. 1.5 seconds to finish. Can somebody describe me, what happened?? This effect holds on until I restart my application. [Edited by - Coder on May 22, 2005 4:50:25 PM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Flash2005
If I run the GDI-Test it always needs approx. 6 seconds to finish. And I can repeat this as often as I want .. its always near to the 6 seconds. But if I do the DirectDraw-Test and after that start the GDI-Test again it is much more faster! Now it only need approx. 1.5 seconds to finish. Can somebody describe me, what happened?? This effect holds on until I restart my application.
Good question, I've noticed similar anomalies myself.
Another interesting thing is that there's often a large speed is that there's often a large difference in performance between performing GDI blits from DIB bitmaps and the equivalent GDI blits from DirectDraw surfaces (with IDirectDraw::GetDC).

You really shouldn't be different pixel formats for the source bitmap and the display, especially not mixing between rgb and palettized modes. How did you get DirectDraw to perform any color conversion at all?

Despite conducting such a test ourselves (between GDI, DirectDraw and DirectGraphics, on 20 machines or so) we haven't been able to predict their relative performance with any accuracy yet.
GDI is often the fastest on new hardware although some new machines (and almost all of the older ones) prefer DirectDraw, DirectGraphics was rarely the fastest but often the most stable and excells at pixel format conversions.

Share this post


Link to post
Share on other sites
Okay, this is my first project in Visual C++. Till now I worked with the more comfortable C++ Builder and old style console C. Also this is my first try using DirectX, so my benchmark may be a bit like comparing apples with pears because I do not use exactly the same functions to get the similar result. I just use "common" functions to get the same result (=moving some sprites with transparency around the screen). Hope you can get the point? So I did not use DDraw:GetDC and other GDI-like DD-functions except FastBlt. I wrote this little class for my Sprites:

class DXSprite
{
private:
int X;
int Y;
LPDIRECTDRAWSURFACE7 lpddsSprite;
public:
DXSprite(int Xoffset, int Yoffset, char *filename, int width, int height, LPDIRECTDRAW7 &lpDD, LPDIRECTDRAWSURFACE7 &back)
{
X=Xoffset;
Y=Yoffset;
lpddsSprite = DDLoadBitmap(lpDD, filename, width, height);
DDSetColorKey(lpddsSprite, RGB(0, 0, 0));

}
~DXSprite()
{
lpddsSprite->Release();
lpddsSprite = NULL;
}
void MoveSprite(int Xoffset, int Yoffset)
{
X+=Xoffset;
Y+=Yoffset;
}
void DrawSprite(LPDIRECTDRAWSURFACE7 &lpddsBack)
{
lpddsBack->BltFast(X, Y, lpddsSprite, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY );
}
};


There is also a function that does the flipping for all the sprites on lbddsBack. I do not have any problems with pallettes if I use 800x600@16bit. If I return to 8 bit mode I get some ugly flickering and fragments on the screen. I used 16bits because I assumed that the desktop is also set to 16 bit to get a better comparison. So I didn't bother any more about pallettes (*please dont kill me*). In my machine there is an old Riva TNT2, but I will test it on a GeforceFX soon.

[Edited by - Coder on May 22, 2005 4:31:59 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Flash2005
There is also a function that does the flipping for all the sprites on lbddsBack. I do not have any problems with pallettes if I use 800x600@16bit. If I return to 8 bit mode I get some ugly flickering and fragments on the screen. I used 16bits because I assumed that the desktop is also set to 16 bit to get a better comparison. So I didn't bother any more about pallettes (*please dont kill me*). In my machine there is an old Riva TNT2, but I will test it on a GeforceFX soon.
Heh, don't worry. I was just refering to that your original post claimed to use 8-bit pixels while the code was setting 16-bit display mode instead.

But as long long as they match you shouldn't have any problems. So make sure you either use native bitmaps in GDI or DIBs exactly matching the screen's format (probably through BI_BITFIELDS).

Maybe returning from fullscreen mode is moving the window around a few pixels? I've experienced huge performance drops with unaligned GDI blits on a TNT2 card before.
It's a long shot but you could try moving the window a few pixels horizontally a little yourself to see if you notice any differences.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • 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!