Poor framerate for simple ops...

Started by
6 comments, last by Bullmax 22 years, 2 months ago
Hi there, I have a ...weird problem, the slowdown type. It''s about my fps in my engine. The "thing" is that my engine runs at 150-170 fps with dx on quite good machine : P3 800 with Matrox G400. But it is the fps when I''m doing nothing ! Maybe it''s my message loop...dunno, but it is not hardcore message loop where a lot of things happen. -I erase the screen... -Do Begin and End scene methods -Present() -I also calculate fps -Check for lost device -There is a GetAsyncKey() call too to quit by pressing escape and that''s all !! I don''t understand or there is nothing to understand, but some microsoft samples run at 540 fps on the same machine, so there is something, no ? ....help... /* Bullmax */ ------------- Reality has many forms : good and evil, black and white, ying and yang.
/* Bullmax */-------------Reality has many forms : good and evil, black and white, yin and yang.
Advertisement
What are you using to render your font?

Moe''s Site
so what is the framerate when youre doing nothing and what are you doing when youre doing nothing???
are you calling present() directly after clear?
or...
are you sure youre measuring the framerate correctly,
is the code that counts the frames executed when you do nothing...
post a little more info, and maybe...

bye,
-- foobar


Edited by - foobar on January 31, 2002 3:56:29 PM
--- foobarWe push more polygons before breakfast than most people do in a day
Ok... here is my master clock class that wraps the high performance counter

      CMasterClock::CMasterClock( void ){	m_iFps			= 0;	m_qwFrameDelay	= 0;	m_iFrameCounter	= 0;	m_qwLastTime	= 0;	m_qwLastCount	= 0;	m_qwFrequency	= 0;}CMasterClock::~CMasterClock( void ){}INT CMasterClock::GetFps( void ){	return (m_iFps);}void CMasterClock::SetMaxFps( INT iMaxFps ){	if (m_qwFrequency)		m_qwFrameDelay = m_qwFrequency / iMaxFps;	else		m_qwFrameDelay = 1000 / iMaxFps;}void CMasterClock::Initialize( INT iMaxFps ){	m_iFps			= 0;	m_iFrameCounter	= 0;		if (QueryPerformanceFrequency( (LARGE_INTEGER *) &m_qwFrequency ))	{		m_qwFrameDelay = m_qwFrequency / iMaxFps;		QueryPerformanceCounter( (LARGE_INTEGER *) &m_qwLastTime );		QueryPerformanceCounter( (LARGE_INTEGER *) &m_qwLastCount );	}	else	{		m_qwFrameDelay	= 1000 / iMaxFps;		m_qwLastTime	= GetTickCount();		m_qwLastCount	= GetTickCount();	}}HRESULT CMasterClock::FrameSync( void ){	INT64 qwCurrentTime;	if (m_qwFrequency)		QueryPerformanceCounter( (LARGE_INTEGER *) &qwCurrentTime );	else		qwCurrentTime = GetTickCount();	if (qwCurrentTime - m_qwLastTime > m_qwFrameDelay)	{		m_qwLastTime = qwCurrentTime;		return (S_OK);	}	else		return (E_FAIL);}void CMasterClock::CalculateFps( void ){	INT64 qwCurrentTime;	if (m_qwFrequency)		QueryPerformanceCounter( (LARGE_INTEGER *) &qwCurrentTime );	else		qwCurrentTime = GetTickCount();	if (qwCurrentTime - m_qwLastCount > (m_qwFrequency ? m_qwFrequency : 1000))	{		m_iFps = m_iFrameCounter;		m_iFrameCounter = 0;		m_qwLastCount = qwCurrentTime;	}	else		m_iFrameCounter++;}void CMasterClock::Freeze( DWORD dwMilliseconds ){	if (m_qwFrequency)	{		INT64 qwStartTime;		INT64 qwCurrentTime;		INT64 qwEndTime = dwMilliseconds * m_qwFrequency / 1000;		QueryPerformanceCounter( (LARGE_INTEGER *) &qwStartTime );		QueryPerformanceCounter( (LARGE_INTEGER *) &qwCurrentTime );		while (qwCurrentTime - qwStartTime < qwEndTime)			QueryPerformanceCounter( (LARGE_INTEGER *) &qwCurrentTime );	}	else	{		DWORD dwStartTime = GetTickCount();		while (GetTickCount() - dwStartTime < dwMilliseconds);	}}      


At startup, I call:
void CMasterClock::Initialize( INT iMaxFps )

and to measure time, at each frame, I call:
void CMasterClock::CalculateFps( void )

To show my Fps, I do this
CHAR INFO[50];
sprintf( INFO, "FPS:%d\n", MasterClock.GetFps() );
OutputDebugString( INFO );

This way, after runnning it, I check the debug output


/* Bullmax */
-------------
Reality has many forms : good and evil, black and white, ying and yang.

Edited by - Bullmax on January 31, 2002 9:17:56 PM

Edited by - Bullmax on February 1, 2002 8:08:23 AM
/* Bullmax */-------------Reality has many forms : good and evil, black and white, yin and yang.
Here is my game loop.... it''s a little complicated to show it because it is chunked. Take a look....

By initializing my windows in other functions, I set up a function pointer like this.
  HRESULT DX_INIT( .., .., .., LoopProc, .., .. ){	p_fpGameMain = LoopProc;	return (S_OK);}//// my function declaration //VOID Game_Main( VOID );//// from game init function //DX_INIT( .., .., .., Game_Main, .., .. );//  


The "raw" message loop"
  HRESULT DX_MessageLoop( VOID ){	p_dwAppStart = GetTickCount();		p_blnAppRunning = TRUE;	do	{		if (PeekMessage( &p_msgWindow, NULL, 0, 0, PM_REMOVE ))		{			TranslateMessage( &p_msgWindow );			DispatchMessage( &p_msgWindow );		}		p_fpGameMain();	}	while (p_blnAppRunning);	p_dwAppEnd = GetTickCount();	return (S_OK);}  


The game loop
  VOID Game_Main( VOID ){	CHAR strFps[64];	sprintf( strFps, "Running at %d frames per second\n", g_clkMaster.GetFps() );	OutputDebugString( strFps );	g_clkMaster.CalculateFps();	DG_Clear();	if SUCCEEDED(DG_BeginScene())	{//DRAWING STARTS HERE//	//DRAWING ENDS HERE////	DG_EndScene();	}	DG_Flip();}  



/* Bullmax */
-------------
Reality has many forms : good and evil, black and white, ying and yang.
/* Bullmax */-------------Reality has many forms : good and evil, black and white, yin and yang.
Hi Bullmax,

In the CMasterClock::Freeze function I see two while loops
that look suspicious, try adding a sleep to the while loops or
do not call that freeze function at all. It may not sound like
this is the problem but I have had similar ones in the past.

Nick
all looks fine except 2 things.
id not use the performance counter (but only because dont like it and timeGetTime() was alwasy sufficient for me).

what you could try is to disable any synchronization and let dx sync you to screen-refresh on flip/present just like nick316 suggested to turn off "waitstates".

you still didnt write what you ment by "doing nothing".
dont draw anything, and directly present the empty frame?
i dont get it.

bye,
-- foobar
--- foobarWe push more polygons before breakfast than most people do in a day
What Imeant by doing nothing was my main loop wich was only presenting the cleared buffer...

But I think that my fps had a limit because I used the D3DPRESENT_INTERVAL_ONE. It syncs me to the refresh rate... Putting it to D3DPRESENT_INTERVAL_IMMEDIATE gives me a little more boost a little more.

I've also noticed that I do not clear, the fps goes to 300 fps. But what I do each frame was posted up there.

tanx

-----
Also, I can draw 608 quads using my blit manager without dropping too much the fps. After that, it drops at each quad that I had.
-----


/* Bullmax */
-------------
Reality has many forms : good and evil, black and white, ying and yang.

Edited by - Bullmax on February 3, 2002 7:20:54 AM
/* Bullmax */-------------Reality has many forms : good and evil, black and white, yin and yang.

This topic is closed to new replies.

Advertisement