Bug in VSync behaviour in WindowedMode and ExclusiveFullscreen

I’m struggling since a while with running my app by default with VSync off and seems that only pressing once Alt Tab partially solves the problem.

Unity 2023.1 - Windows 10, Nvidia 3050.

Project/Quality settings are no Vsync (VSync 0 ) and Exclusive Full screen, Target frame rate -1.
Did the regedit reset because of the known bug that doesn’t refresh them after each built.

Please note that I tried any possible combination of Project/Quality settings and also setting Fullscreenmode and Vsync by script and leaving the defaults (see later).
Note also that I tried any possible combination of Windows settings, Nvidia settings/panel, XBox panel off, regedit as aforementioned, windowsgraphic settings and Hardware specific/Vendor related setting. Also all the possible permutations of the above.

This is a Build for Windows when starting playing:

This is what happens after pressing once AltTab and nothing else:

This is instead how it runs after going in my InGameVideoOptions, and setting in FullScreenWindowMode (VSync is still off) as you can see VSync gets forced on. Actually I never managed to have it off in fullscreeenwindows (alt tab does nothing).Note 60fps and not 30fps like in the first pic:

This is how it runs after enforcing by script:

Setting from script:
Screen.fullScreenMode = FullScreenMode.ExclusiveFullScreen;
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = -1;

In picture how the game runs at start.
Also, pressing alt tab in this case changes nothing and looking at my InGame options the fullscreenmode is actually FullScreen window and not exclusive as it was supposed to be due to the code before.

Still in game, going to the InGame options and switching to Exclusive Full screen goes back to:

So basically I could not find a way to start a game with my settings having either Fullexclusive without Vsync or even better FullScreenWindow without Vsync.

Behaviour seems to be completely erratic.

Note that I can turn on Vsync in Exclusive mode too and it works as expected, behaving like the other pictures above.

1 Like

Hey what does the GPU usage look like when it gets locked at 30 fps? Could you record me an ETW trace with “CPU Usage” with “GPU Usage” activity of this happening? A guide on how to do that is here: Recording a trace on PC

Hello,

I don’t have the source code at hand right now on this machine, it will take a while before I do (I’m traveling this next weeks).

But reading again the post I did (was one year ago) I think there is enough information to reproduce the problem, did you try without success?

If the question is related to cpu/gpu load making them wait each other I can assure you that’s not the case. I had made extensive checks on that. Also you can see by alt tabbing I could disable the Vsync happening, thus I’m quite sure it was related to Unity not setting something properly or enforcing Vsync in some instance when this is disabled/not required.

I just found some time to try to reproduce it. I copied your code and added some code to print frame rate & full screen mode:

using System;
using System.Globalization;
using UnityEngine;

public class NewMonoBehaviourScript : MonoBehaviour
{
    string m_FrameRate;
    GUIStyle m_LabelStyle;
    int m_FrameCount = 0;
    double m_LastFrameRateTiming;

    void Start()
    {
        Screen.fullScreenMode = FullScreenMode.ExclusiveFullScreen;
        QualitySettings.vSyncCount = 0;
        Application.targetFrameRate = -1;

        m_LastFrameRateTiming = Time.timeAsDouble;
        m_FrameRate = "Calculating...";
    }

    void Update()
    {
        m_FrameCount++;

        var time = Time.timeAsDouble;
        var timeDiff = time - m_LastFrameRateTiming;
        if (timeDiff >= 0.5)
        {
            m_LastFrameRateTiming = time;
            m_FrameRate = (m_FrameCount / timeDiff).ToString("#.00", CultureInfo.InvariantCulture);
            m_FrameCount = 0;
        }
    }

    private void OnGUI()
    {
        if (m_LabelStyle == null)
        {
            m_LabelStyle = new GUIStyle(GUI.skin.label);
            m_LabelStyle.fontSize = 36;
        }

        GUILayout.BeginVertical();
        GUILayout.Label("Full Screen Mode: " + Screen.fullScreenMode, m_LabelStyle);
        GUILayout.Label("VSync: " + QualitySettings.vSyncCount, m_LabelStyle);
        GUILayout.Label("Frame rate: " + m_FrameRate, m_LabelStyle);
        GUILayout.EndVertical();
    }
}

This is the result I got when I launched the build:

I honestly suspect some driver shenanigans here in your case. Have you tried this on another machine?

Hello, yes it was tested on different machines.

As I was mentioning, my guess would have been that this bug is related to the resolution/registry key we already addressed.

Thus a more reliable way to reproduce it could be doing something similar, setting the build to windowed and Vsync active => producing a build.
Then changing back the settings / altering it by code and producing another build. (a button to change windowed/Vsync could help).

You can use Time.Delta to simplify the above code.

Reading around at the time I had found out that it was a known bug. Developers had no way to force Vsync in exclusive Fullscreen or viceversa, controlling it in windowed mode.

The solution pushed by Unity was to deprecate exclusive fullscreen …

My understanding was also that this bug is the reason thousands of users complained over the years about Unity melting their computers in the Main Menu of games … ( rendering a main menu at 2000fps) … and developers answering in the support forums that the problem was Unity not changing properly some settings … (and the opposite is also true, VSync On when not wanted).

I don’t think that could actually be the case: the fullscreen mode and vsync are controlled by the script and it overwrites whatever startup settings may have been chosen.

Can you post any links/bug numbers? I cannot recall any such bugs ever existing and I’ve been maintaining this code for the last decade.

This never happened. It’s an urban legend among gamers who play games that decided to not include this option.

Usually what happened in those cases is that the VSync was forced off through the driver. Unity cannot override what you configure in driver settings.

Thank you for taking the time to try to address the issue.

I’m not convinced the problem are the drivers, I will look again into that as soon as I have time and the code at hand.