PDA

View Full Version : problem with DEVICE.PRESENT method in Delhi8



alex_izm
21-12-2005, 05:31 PM
Greetings, fellow programmers.

Recently I?_Tve started learning Delphi 8 and .NET framework. I have downloaded DirectX SDK for managed code with examples and also found samples converted into Delphi. I managed to compile and run most of them, but I?_Tve noticed that DEVICE.PRESENT method decreases FPS down to around 30 even on the simplest program. When I take the line out, of course there is no buffer flip and nothing is displayed, but FPS jumps up to around 7000. My question is, has anybody encountered anything like this? And if so, what am I doing wrong?

Thanks in advance.
Alex

p.s. Clootie, how are you doing, man? It?_Ts been a while.:D

JSoftware
21-12-2005, 06:49 PM
maybe you have choosen a wrong backbuffer format?

Clootie
22-12-2005, 07:42 PM
VSync ?

alex_izm
22-12-2005, 08:43 PM
Thanks for your comments.


maybe you have chosen a wrong backbuffer format?
No, I've tried that too. I tried it with default format (presumably the same as desktop format). and then I've tried to set backbuffer format to a number of different values. No effect whatsoever.


VSync ?
Swapeffect is set to discard. But even if VSync is on, refresh rate of my monitor is 60 and the application is very simple. But I get around 30FPS.

JSoftware
22-12-2005, 09:27 PM
may we see your rendering code and d3d init code?

Clootie
22-12-2005, 09:28 PM
30 == 60 / 2

So if your app requires more than 17ms to render single frame - you'll be getting 30 FPS. This is common issue with games for example.

alex_izm
23-12-2005, 01:39 AM
may we see your rendering code and d3d init code?
here it is:


{$REGION 'Direct3D procedures'}
procedure twinform.initd3d();
var presentParams:presentparameters;
begin
presentParams := PresentParameters.Create;
presentParams.Windowed:=true;
presentParams.SwapEffect:=SwapEffect.Discard;
presentparams.BackBufferCount:=1;
presentparams.BackBufferWidth:=self.ClientSize.wid th;
presentparams.BackBufferHeight:=self.ClientSize.he ight;

device1 := Device.Create(0, DeviceType.Hardware, self, CreateFlags.HardwareVertexProcessing, [presentParams]);
end;

procedure twinform.render1();
begin
device1.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1, 0);
device1.BeginScene();

device1.EndScene();
device1.Present();
end;
{$ENDREGION}



30 == 60 / 2

So if your app requires more than 17ms to render single frame - you'll be getting 30 FPS. This is common issue with games for example.

That is true (I hate VSYNC for that), but I have a very fast machine and the application is very simple. And also when I comment the line "device1.present();" out, FPS increases substentially.

Actually, I've just ran the this thing again with "device1.present();" commented out. FPS jumps wierdly between 17 and 80000. When I comment "device1.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1, 0);" line FPS stays stady around 500000. Here is the piece of code where I count FPS



var thistick,lasttick,frames:integer;
fps:single;

//counting FPS
inc(frames);
thistick:=environment.get_TickCount;
if thistick-lasttick>100 then begin
fps:=frames*1000/(thistick-lasttick);
label1.Text:=system.String.Format('FPS: {0}',[fps.tostring('00000000.00')]);
frames:=0;
lasttick:=environment.get_TickCount;
end;


Thanks

JSoftware
23-12-2005, 01:29 PM
thistick:=environment.get_TickCount;
if thistick-lasttick>100 then begin
fps:=frames*1000/(thistick-lasttick);
label1.Text:=system.String.Format('FPS: {0}',[fps.tostring('00000000.00')]);
frames:=0;
lasttick:=environment.get_TickCount;
end;

try the safe way of doing it:

thistick:=environment.get_TickCount;
if thistick-lasttick>1000 then begin
fps:=frames;
label1.Text:=system.String.Format('FPS: {0}',[fps.tostring('00000000.00')]);
frames:=0;
lasttick:=thistick;
end;

Clootie
23-12-2005, 08:50 PM
1) Did I understood right that there is no code between:
device1.BeginScene();

device1.EndScene();
?

2) With "Present" commented out no work will be acually done to render anything (I mean videocard driver will not even start rendering current frame until you call Present).

3) From MSDN (btw, why are you using "get_TickCount" and not just "TickCount" in Delphi.net?)

The resolution of the TickCount property cannot be less than 500 milliseconds. So it's really bad idea to you it as high precision counter. Probably something like Date.Ticks will be much better, but I actually don't know details of CLR.

JSoftware
23-12-2005, 08:53 PM
the windows gettickcount is very precise down to 5milliseconds i read this in an article somewhere where they were comparing different timing methods. ofcourse frequency counter was the most precise but gettickcount was enough precise too. i don't know is that .net stuff you are using there?

Clootie
23-12-2005, 09:48 PM
MSDN GetTickCount: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/gettickcount.asp
On this page: "If you need a higher resolution timer, use a multimedia timer or a high-resolution timer."

About Timers -> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/timers/abouttimers.asp

Basically in Win32/Win64 you have two choices:
1) use QueryPerformanceCounter etc.
2) use timeGetTime, but at application start call timeBeginPeriod(1); and in finalization timeEndPeriod(1); to set precision to 1ms under WindowsNT based OS'es

alex_izm
25-12-2005, 04:36 AM
Thanks for your replies
Appreciate the time spent:)


2) With "Present" commented out no work will be acually done to render anything (I mean videocard driver will not even start rendering current frame until you call Present).


I could be wrong, but I thought Device.Present just flips the backbuffer on a primary surface, does it not? And method Device.Clear in this case fills the backbuffer with blue color. So if Device.Present is commented out, the app will just fill the backbuffer every frame. The rendering (if you can call it that) will occur, only it will not be visible.

When I comment out Device.Clear, then nothing gets rendered at all and FPS skyrockets.

Thanks for your tips with timers. Most helpful.

I'm starting to think, it is not the program. I ran the first tutorial from the DirectX SDK October 2005 and had the same issue. Could it be something else? For instance, I have .NET framework version 1.1 installed. Do I need version 2 maybe? Or could it be my overclocked Graphics adapter? Or may be it is a bug in Delphi compiler?

So I guess my next question is has anyone actually had the same problem (see the topic), when running Direct3D application developed with Delphi 8 and DirectX for managed code SDK October 2005?

Thanks,
Alex