VSync messing with QPC() timing?

Started by
12 comments, last by Pygmyowl 10 years, 8 months ago

If the refresh rate is at 60HZ and your rendering consistently at 59HZ i is going to duplicate frames. If you cant use a Present like I mentioned (I just looked at the IDXGISwapChain and it seems to have flags to do so for Present) then I think you need to render at slightly above the refresh rate, so that it still gets all the frames it needs, with minimum time spent waiting on a vsync.

Since you've mentioned IDXGISwapChain, does your method require DirectX 10 or higher?

Have you got D3DCREATE_FPU_PRESERVE in your CreateDevice call? If not I'd suggest that you put it in there as a temporary workaround, and doing so should resolve your problem, which sounds an awful lot like you're accumulating time deltas and suffering from floating point precision loss in the accumulation.

Sadly, adding the flag did nothing. I've mentioned before that, as per Hodgman's suggestion, this is probably a frame queueing problem.

Advertisement


Since you've mentioned IDXGISwapChain, does your method require DirectX 10 or higher?
On Direct3D9, on Vista/Win7, you can create a IDirect3DDevice9Ex device instead of a IDirect3DDevice9 device, which then lets you use the PresentEx function with the D3DPRESENT_DONOTWAIT flag.

AFAIK D3DPRESENT_DONOTWAIT is completely ignored by NVIDIA and Intel drivers.

Speaking of which, I tried obtaining the swap chain pointer from the device (using GetSwapChain) and calling Present from that (it has a flag parameter, like PresentEx), but D3DPRESENT_DONOTWAIT didn't have any effect. As it happens, my laptop has Intel and NVidia GPUs.

That said, is PresentEx any different from what I've tried? Should I give it a go nonetheless?

Update: I've come across an article describing the use of GetRasterStatus to determine if the frame is still being drawn. Adding this to my second timer check (so the render function isn't called until the display has finished drawing) seems to have fixed the problem.

Just in case, the second check now looks like this:


if((timer.tickCount.QuadPart-timer.memory1.QuadPart)>=(timer.tickFreq.QuadPart/GlobalParams.MaxFPS))
{
	d3ddev->GetRasterStatus(0,&d3drst);
	if(d3drst.InVBlank==true)
	{
		FramePass();
		phystick=0;
		timer.memory1.QuadPart=timer.tickCount.QuadPart;
	}
}

Are there any potential problems I'm not seeing?

This topic is closed to new replies.

Advertisement