FPS and VSync

Hi,

How can I count FPS with no VSync limit?
If my monitor has 85 Hz refresh frequency my function returns 85 FPS max. How to get way around it?

thanx

you have to disable vsync on your card. I have a Geforce 4 Ti4200 so I use an excellent utility called RivaTuner to disable the vsync whenever I want to test performance

Look at the WGL_EXT_swap_control extension.

– Ben

Well, I was thinking about the same. I also get monitor’s frequency as a result of fps calculating function. I think opengl enables v-sync it automatically. I saw DirectX program which run on 300 fps. I am also looking for the answer.

If you’re running under win32, the following code may help:

// define extension proto
typedef void (APIENTRY * PFNWGLSWAPINTERVALEXTPROC)(int interval);

// instance the extension
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;

// after system initialization
// bind to address
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress(“wglSwapIntervalEXT”);

// if valid, disable vsync
if(wglSwapIntervalEXT != NULL)
wglSwapIntervalEXT(0);

This will disable vsync, allowing both windowed and fullscreen apps the potential to run well above the refresh rate. Be careful, however, as this also can introduce a lot of tearing and/or “jaggies” issues.

Hope this helps,
Dave

Hi,

This is fragment of Quake code, I think this is special function to swap buffers. This function checks does vsync is enabled.
There are also some assembler parts - they
are responsible for vsync I think.

BTW: I haven’t got the option in my GF2 to disable VSync (I didn’t found it), quake sets it itself.

void VID_ExtraSwapBuffers (viddef_t *lvid, vmode_t *pcurrentmode,
vrect_t *rects)
{
int pageoffset;

UNUSED(rects);
UNUSED(pcurrentmode);

pageoffset = VID_pagelist[VID_currentpage];

// display the newly finished page
if (lvid->numpages > 1)
{
// page flipped
regs.x.ax = 0x4f07;

	if (vid_wait.value != VID_WAIT_VSYNC)
	{
		if ((vid_wait.value == VID_WAIT_DISPLAY_ENABLE) && de_exists)
			VID_ExtraWaitDisplayEnable ();

		regs.x.bx = VESA_DONT_WAIT_VSYNC;
	}
	else
	{
		regs.x.bx = VESA_WAIT_VSYNC;	// double buffered has to wait
	}

	regs.x.cx = pageoffset % VGA_rowbytes;
	regs.x.dx = pageoffset / VGA_rowbytes;
	dos_int86(0x10);

	VID_displayedpage = VID_currentpage;
	if (++VID_currentpage >= lvid->numpages)
		VID_currentpage = 0;

//
// set the new write window if this is a banked mode; otherwise, set the
// new address to which to write
//
	if (VID_banked)
	{
		regs.x.ax = 0x4f05;
		regs.x.bx = 0;
		regs.x.dx = VID_currentpage;
		dos_int86(0x10);
	}
	else
	{
		lvid->direct = lvid->buffer;	// direct drawing goes to the
										//  currently displayed page
		lvid->buffer = VID_membase + VID_pagelist[VID_currentpage];
		lvid->conbuffer = lvid->buffer;
	}

	VGA_pagebase = lvid->buffer;
}
else
{
// non-page-flipped
	if (vsync_exists && (vid_wait.value == VID_WAIT_VSYNC))
	{
		VGA_WaitVsync ();
	}

	while (rects)
	{
		VGA_UpdateLinearScreen (
				lvid->buffer + rects->x + (rects->y * lvid->rowbytes),
	 			VGA_pagebase + rects->x + (rects->y * VGA_rowbytes),
				rects->width,
				rects->height,
				lvid->rowbytes,
				VGA_rowbytes);

		rects = rects->pnext;
	}
}

}

The code you posted is for “swapping” VGA buffers. It doesn’t have anything to do with OpenGL (looks like it’s from the DOS version of Quake).

What you’re really interested in (as I said before) is the WGL_EXT_swap_control extension, found here . Dave.D gave you some good example code showing you how to use it.

– Ben

What do you mean turning vsync off allows fps above the refresh rate???

That is a myth. There is no free fps. If your monitor is set to 85Hz and vsync is off and an fps counter is showing 170fps all this means is that the card is throwing a 2nd frame at the monitor before it has finished one refresh. As far as the monitor is concerned the frame rate is still 85fps. I only use vsync off to benchmark frame time.

That’s what causes tearing. You are seeing frame 2 before you are meant to.

I read somewhere that WinXP internally limits DirectX frame rates to around 75fps and OpenGL to around 60fps though you can download fixes for this.

You should ONLY disable VSync (using WGL_EXT_swap_interval) for benchmarking purposes. The only visual “improvement” is ugly tearing. Another side effect of disabling VSync is that you always use 100% CPU, which is quite unnecessary.

You can (and should) use WGL_EXT_swap_interval to ENABLE VSync: wglSwapIntervalEXT(1).

Originally posted by eXor:
I read somewhere that WinXP internally limits DirectX frame rates to around 75fps and OpenGL to around 60fps though you can download fixes for this.

I think you are refering to the way that Windows selects video modes for you. Unless you explicitly say what refresh rate you want XP (and 2K) selects a 60 Hz mode (at least for OpenGL). This is a safety precaution to not damage your monitor. In contrast, Win9x selects the HIGHEST possible refresh rate if no specific refresh rate is selected, which, imo, is a bad thing (what if your monitor driver and monitor do not match? => black monitor).

Whether or not you lose CPU is up to you
I always throttle my frame rate to 100fps with a CPU friendly:

				elapsedTime=stopTime - startTime;
				renderTime=elapsedTime; // get true render time in case of need for throttle

				if (throttle > elapsedTime)		// Keeps frame rate below 100fps
				{								// when vysnc is disabled
					
					Sleep(throttle-elapsedTime);
					elapsedTime=throttle * timeScale; // convert to seconds
				}

So if vsync happens to be disabled on the system running it, it won’t go above 100fps.
Run a few threads alongside during the sleep and you’re laughing

Originally posted by eXor:
Whether or not you lose CPU is up to you

Yes, your solution is acceptable if VSync is disabled. What I meant is that you should try to enable VSync first. If that fails, you can resort to some method to offload the CPU.

Of course, you normally want to be able to run your app with VSync off & 100% CPU utilization too, since it is a good way to benchmark your program. I guess that with your method, you can keep track of how much time is spent on sleeping and how much time is spent on rendering etc - which in itself is a good benchmark figure (virtual FPS = actual FPS / CPU utilization).