0

pretty new on the C++ side of windows - special non-Win32 such as UWP -

I am trying to cap FPSs at a steady 60 FPS by simply ticking (Update/Render) every 1000/60 milliseconds. I am facing a strange situation though. If I am using Present(0,0), the swap chain will lock and v-sync automatically, all good. If I use Present1(0,DXGI_PRESENT_DO_NOT_WAIT, &params) ... I hit 600 FPSs...

NOW, while letting FPSs free (600), I want to implement my own ticker. So far I have:

bool Ticker::Tick() {

    long currentTick = GetTickCount64();
    long deltaTicks = (currentTick - gLastTick);
    bool tick = false;

    // determine whether it is tick time
    if (deltaTicks >= gUpdateTime) {
        gLastTick = currentTick;
        gTicksCount++;
        char buf[256];
        sprintf_s(buf, "Current delta: %30d\n", deltaTicks);
        OutputDebugStringA(buf);
        tick = true;
    }

    // this metric must happen regardless of actual true Ticks
    if (currentTick - gSecondTime >= 1000) {
        gCurrentFrameRate = gTicksCount;
        gSecondTime = currentTick;
        OutputDebugStringW(L"Second is up\n");
        gTicksCount = 0;
    }

    return tick;
}

Needless to say this is not working... I am hitting 20/21 FPSs when my target is refresh very 1000/60.

I believe I am committing a rather silly mistake but I can't see where.

Thank you.

Fer
  • 460
  • 2
  • 4
  • 17
  • This might sound like a dumb question... but why would you want to cap at 60 fps? What happens when you run it on a 75 Hz monitor? Just do it properly and let Present block - that's the correct way to limit FPS. – Sunius May 28 '16 at 21:42
  • @Sunius well, true, but sometimes you might want more granularity when it comes to adjusting the frame rate regardless of how Present blocks, right? – Fer May 30 '16 at 15:55
  • No, not really. Why would you want to do it? – Sunius May 31 '16 at 05:05

1 Answers1

1

From the doc:

The resolution of the GetTickCount64 function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds.

So as 1000/60 ~ 15ms, the counter resolution is inadequate.

Ilya
  • 5,377
  • 2
  • 18
  • 33
  • Now THAT makes sense... should I be using QueryPerformanceCounter instead? which would be the best solution? Thanks. – Fer Jan 07 '16 at 21:28
  • Yes, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx – Ilya Jan 07 '16 at 21:31
  • 1
    Quote "If you need a higher resolution timer, use a multimedia timer or a high-resolution timer." `QueryPerformanceCounter` should work on most systems I guess. – Ilya Jan 07 '16 at 21:36
  • @Fer And if that answers your question, could you please accept the answer to close the issue ...? – Ilya Jan 08 '16 at 20:06