I'm trying to achieve steady fixed 60fps in my D3D app and to do that by doing vsync. I've setup loop like this:
while(isRunning)
{
ProcessMessages(window);
renderer->context->ClearRenderTargetView(renderer->renderTarget, color);
renderer->swapChain->Present(1, 0);
end = GetCurrentTick();
double ms = GetElapsedMilliseconds(start, end);
start = end;
}
// Function definitions
inline LONGLONG GetCurrentTick()
{
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return count.QuadPart;
}
inline double GetElapsedMilliseconds(LONGLONG start, LONGLONG end)
{
return (1000.0 * (double)(end - start)) / (double)freq.QuadPart;
}
I would expect to see "ms" variable to be always the same, but it's actually varying from around 16.1 ms to something over 17. Is there some wrong assumption I'm making or just plain coding error? Thanks for help in advance.
Empty-loop timing is not particularly accurate and can be easily confounded, so you should create something that has an actual scene instead. You can then use GPUView or similar tools to figure out any stalls in your code.
What is happening here is Windows lets you queue up 3 frames, then puts your thread to sleep until one is processed then readies it again. The default scheduler quantum is 15 ms, so you get that much of a delay once you are in this steady state of basically being held by the Present queue.
You can detect this behavior in your code if you use
DXGI_PRESENT_DO_NOT_WAIT
in your Present, in which case you'll get a failure code backDXGI_ERROR_WAS_STILL_DRAWING
rather than having your thread put to sleep.Also, you did not mention which flip model you are using.