Archived

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

Poor framerate for simple ops...

This topic is 5791 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 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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites