Vsync not (force) enabled on Windows.
marcel303 opened this issue · comments
This issue is causing high CPU load and difficulties navigating the UI.
Perhaps this will need to be addressed through OpenGL driver extensions?
I did some more testing. This is a bit of a wall of text, but I have a summary at the bottom.
I thought it was weird that vsync was working in Linux but not in windows. So I checked to see if the intel graphics drivers in Linux were forcing vsync on globally by default, and they were. After some effort and some config tweaking I was able to get the drivers set so that vsync would be application controlled, but off by default. By doing this I was able to determine for certain that, in Linux, kdreams is actually turning on vsync when it is allowed to do so. I also discovered I could use steam to monitor the FPS in Linux the same way i could in windows, which helped to diagnose.
I copied my windows build over to an old Windows 7 pc with Nvidia graphics, and I had to install the x86 vc 2017 redistributable to get it to work. Then I tested it, and vsync worked the way it was supposed to, and the way it does on linux (vsync off when set to off, and on when set to on or application controlled), but cpu usage was still very high. About 50%. This is an old pc, but the cpu usage was the same whether vsync was on or off. It's very odd. Also, for some reason windows 7 seems to think the program has crashed every time I shut it down. It looks like it might have something to do with the console window not closing automatically?
I had a second Windows 7 pc I could test on - this one with ATI graphics. And on this one, the vsync also worked correctly, and the cpu usage was low with the vsync on.
I had another windows 10 pc and I decided to test it. The vsync settings were a little different despite them both being intel. With vsync set to "application controlled", vsync was off in kdreams, but with vsync set to "driver controlled" vsync was on. This is similar to how it works on the Windows 10 laptop, only the settings on the laptop except with "application controlled" replacing "application settings" and "driver controlled" replacing "on".
I suspect that the problem with Windows 10 either lies in a change to Windows 10, or something weird with the intel driver on the machine. Windows 10 updates have been breaking all kinds of stuff lately so that's very possible. I did some testing and vsync seemed to work ok in other games, but it was difficult to to tell with 100% certainty.
I also did some more testing on the laptop and with /nogl /fullscreen the game feels like vsync is on. There's no tearing, and the menu reacts as if vsync is on, but the cpu usage is still high. With /nogl in a window the game feels like vsync is off - at least in the menu. I was unable to get the fps overlay to display while using /nogl (neither steam nor fraps).
It may not be relevant, but:
- The linux machine has an Intel HD Graphics 2000 chipset
- The windows 10 (version 1803) laptop has an intel HD Graphics 3000 chipset
- Other Windows 10 (version 1803) pc has an Intel HD Graphics 2500 chipset
- One Windows 7 machine has an Nvidia Geforce 6150SE chipset.
- The other Windows 7 machine has an ATI Radeon RS880 (HD 4200?) chipset
To summarize
- Linux - On when set to on or application controlled. Off when set to off. Cpu usage high when off and low when on.
- Windows 10 (version 1803) with Intel graphics(2 machines tested) - On when set to on. Off when set to off or application controlled.
- Windows 7 with Nvidia graphics - On when set to on or application controlled. Off when set to off. Cpu usage always high.
- Windows 7 with ATI graphics - On when set to on or application controlled. Off when set to off. Cpu usage high when off and low when on.
Edit: I had one more pc I could test on, and I've added it to this comment. The high cpu usage on the Win7 with Nvidia system, while vsync is on, seems to be an anomaly among all the systems I tested.
I looked into this a little and I noticed that the sdl 1.2.15 release notes said ""Use the OpenGL GLX_EXT_swap_control extension if available", but only under unix. The windows equivalent is "WGL_EXT_swap_control" with "wglSwapIntervalEXT(1)" used to enable vsync on windows and "wglGetExtensionsStringARB()" used to verify that WGL_EXT_swap_control is actually present.
It seems as though SDL 2 has a more robust vsync implementation, but I'm aware that would be a TON of work. GLFW might also have a more robust vsync implementation.
Is there a way to reduce cpu usage and give a consistent frame rate that doesn't rely upon vsync?
Thanks for such a detailed report. I'll play around with the vsync settings on my Windows laptop too when I get the chance. I have Nvidia drivers so I should get similar results as you.
Meanwhile, I added an explicit wait on a condition variable to limit the frame rate. See 10181c9 (+4b47cd0). This should fix the 100% cpu issue. Still, would be nice to actually force vsync on to ensure scrolling is as smooth as possible.