DirectX VSYNC inaccuracy

498 views Asked by At

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.

1

There are 1 answers

1
Chuck Walbourn On

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 back DXGI_ERROR_WAS_STILL_DRAWING rather than having your thread put to sleep.

Also, you did not mention which flip model you are using.