Godot version:
Godot 3.2.3 RC2
OS/device including version:
Linux Mint 19.2, Nvidia Geforce GTX 750 Ti, GLES3
Issue description:
When enough lag is produced while using the Nvidia Rect Flicker Hack and it drops anywhere below 60 FPS, but above 30 FPS then it will drop it to a stable 30 FPS. Anywhere below 30 it will drop to 20, and so on. It would seem it is hitting some preset numbers when it should be flexible as normal allowing for any frame rate to occur.
Steps to reproduce:
Run the included sample project. In it you will notice that I've turned on Nvidia Rect Flicker Hack in the project options under Rendering > Quality > 2D .
When the program is loaded it will continually spawn sprites/lights (depending what you set) until it dips just below 60 FPS. However you will notice that as soon as it does stop spawning them, it will drop down to a stable 30 FPS and stay locked there until nodes are freed or are no longer on-screen. You can see this in the sample by moving the camera with WSAD or the arrow keys.
Minimal reproduction project:
Nvidia Rect Flicker Hack dropping preset divisions of frames demonstration.zip
GeForce GTX 1660 SUPER/PCIe/SSE2
My results:
This might be related to: https://github.com/godotengine/godot/issues/35038
The bug does not occur if you have V-sync off. Are you turning V-sync off in the project settings or have it forced off from your graphic driver configuration utility? Please give your OS details as well.
I don't think this is a bug. V-Sync will always introduce this kind of stuttering, unless you use a variable refresh rate monitor (and the game is configured to make use of it). It might be possible to use triple (or quad) buffering to alleviate it, but this will increase input lag noticeably.
This could be fixed by implementing support for adaptive V-Sync, but it's feature proposal territory.
Calinou, it is not stuttering. As I say in the post it goes into a stable 30 FPS when it should be somewhere between 50-60FPS.
This bug is not present in 3.2.1 where it behaves predictably:
If there was no adaptive V-sync before, then I doubt it's the solution for this problem.
From what I can tell this is a regression.
This is expected behavior:
When frame rates dip below the cap VSync locks the frame rate to the nearest level, such as 45 or 30 frames per second.
(Source: https://www.nvidia.com/en-us/geforce/technologies/adaptive-vsync/technology/)
Thank you for the information, hoontee. I did not know this detail about V-sync, but this only confuses me further.
Why does it then not happen in 3.2.1 stable for me despite the settings being the same (V-sync enabled & Nvidia Rect Flicker Workaround enabled)? Dare I bisect to find it? I warn you I only just learned how recently! Seems it might give us the answer to that question though.
There must have been a slight reduction in performance that set it over the threshold. You should try to find out what might have caused it, whether it be a change made to the engine or something running in the background on your PC. Edit: mystery solved.
CC @lawnjelly
This bug is not present in 3.2.1 where it behaves predictably:
3.2.1 didn't have nvidia workaround for GLES3, it was only GLES2 at that point. The GLES3 version is direct porting of the GLES2 code across.
Agree with Calinou, I don't think there is a bug (in the workaround). The workaround is simply very slow on GLES3, about 1/3 of normal speed. It looks like something is causing you to be vsynced.
With vsync, with occasional slow frames (which is what you might see with other performance limitations) you might get number occurring between 60 and 30. With constant slow frames (which may occur with workaround) you will get more or less instant drops from 60 to 30, to 20, to 15 etc as divisors of the refresh rate, which is what you are seeing.
i.e. with random frame time variations, some will meet the 16.6ms limit for 60 fps, some will miss it, thus on average you will get numbers between 30 and 60. With a constant frame time, you either meet the limit or miss it, which gives a more abrupt drop.
Or maybe it is some GPU driver feature as hoontee suggested.
Incidentally, I'm planning on getting GLES3 batching working soon, which should make less performance problems in this area.
(whoops didn't mean to close straight off, but this does seem more about vsync).
The bug does not occur if you have V-sync off. Are you turning V-sync off in the project settings or have it forced off from your graphic driver configuration utility? Please give your OS details as well.
I ran it as is.
Will close this now as it seems solved, if there's some evidence of a bug, we can reopen.
Sorry I was away for a few days, had to clean out the computer of dust & rearranged the desk :sweat_smile:
I did some more testing just to confirm and lawnjelly is correct.
I did not understand how V-sync would cut the framerate by these margins & to clarify it is my intent to have it enabled. I guess in all my years I never made such an observation though I use V-sync all the time. :flushed: I forgot that the NVidia Rect Flicker Workaround did not apply to GLES3 in version 3.2.1 as well, which was added as a feature in 3.2.2 . I think as a personal solution I will leave it to the player to be able to be able to turn off V-sync & I'll try to migrate the game to 4.0 so we don't need to worry about the rect flickering.
This is not a bug & it's an error of understanding on my part. Though I admit I'm still a bit confused on why V-sync alone doesn't cause this issue in older versions where it will still have a dynamic frame rate when it's on. I can only guess that V-sync was fixed since then and didn't work properly in 3.2.1 and before :shrug:
Most helpful comment
3.2.1 didn't have nvidia workaround for GLES3, it was only GLES2 at that point. The GLES3 version is direct porting of the GLES2 code across.
Agree with Calinou, I don't think there is a bug (in the workaround). The workaround is simply very slow on GLES3, about 1/3 of normal speed. It looks like something is causing you to be vsynced.
With vsync, with occasional slow frames (which is what you might see with other performance limitations) you might get number occurring between 60 and 30. With constant slow frames (which may occur with workaround) you will get more or less instant drops from 60 to 30, to 20, to 15 etc as divisors of the refresh rate, which is what you are seeing.
i.e. with random frame time variations, some will meet the 16.6ms limit for 60 fps, some will miss it, thus on average you will get numbers between 30 and 60. With a constant frame time, you either meet the limit or miss it, which gives a more abrupt drop.
Or maybe it is some GPU driver feature as hoontee suggested.
Incidentally, I'm planning on getting GLES3 batching working soon, which should make less performance problems in this area.
(whoops didn't mean to close straight off, but this does seem more about vsync).