Sodium

Sodium

35M Downloads

RivaTuner Statistics (RTSS) causes extreme performance issues

emilpro2008 opened this issue ยท 27 comments

commented

Bug Description

Upon enabling the MSI Afterburner overlay/Rivatuner Statistics, the game starts to lag. Concurrently, there's a consistent spam of OpenGL debug error messages in the console. These error messages are predominantly of the type "GL_INVALID_OPERATION" and "GL_INVALID_ENUM", saying that OpenGL functions like 'glPushAttrib' and 'glPopAttrib' are deprecated. This behavior does not occur when running the game with Sodium disabled.

The game itself does not crash but experiences significant lag due to these errors.
This issue seems to be exclusive to scenarios where both Sodium and overlays (I've been using MSI Afterburner which for me causes this bug) are active.

Mods I'm using:
Sodium [1.20.1 0.5.2]
Fabric API [1.20.1 0.87.0]

Reproduction Steps

  1. Firstly have fabric api 0.87.0+1.20.1, sodium fabric 1.20.1 0.5.2 and msi afterburner installed
  2. Open up Minecraft
  3. Press your hotkey for msi afterburner overlay
  4. look in either the console or in the latest.log file
    There you go, it should be filled with 100s of thousands of opengl messages

Log File

latest.log

Crash Report

crash-2023-08-27_02.13.17-client.txt

commented

The overlay which RivaTuner provides is rendered using legacy OpenGL functions, and it needs to hook into the game process so that it can enable these functions. Unfortunately, Sodium is also trying to enable a "No Error Context", and that's mutually exclusive with using legacy OpenGL functions, which get disabled when the other is enabled.

There is nothing we can do to actually fix this problem. At best, we can terminate the game instantly if an OpenGL error occurs, to prevent the game from filling the hard drive with logged errors.

commented

Disabling "Use No Error Context" under Video Settings -> Performance should work around this issue, but you will lose a bit of performance.

commented

that's mutually exclusive with using legacy OpenGL functions, which get disabled when the other is enabled.

Is this documented anywhere or was it just discovered through trial-and-error? ๐Ÿ˜† I couldn't find anything about this on the Khronos wiki.

commented

It's not actually described that it should work this way in the OpenGL specification. It's just been my observation with the drivers on Windows. And quite frankly it's the only explanation which makes any sense... though I could be wrong.

commented

If someone finds a way to fix this, then feel free to open a pull request... but as it stands I'm not going to waste my time trying to resolve this -- it's almost impossible to fix issues which are caused by other processes randomly hacking into your application.

commented

Future versions of Sodium will prevent the use of RivaTuner entirely with an error on startup. It's not possible to fix the compatibility issues with it, and having it hooked into the game causes severe problems.

If you depend on Rivatuner, then you can do one of two things:

  • Use the in-game performance overlay which your GPU vendor already provides.
  • Download and install Intel's PresentMon if your vendor doesn't provide a solution, or you don't find it sufficient.
commented

I read whole thread and still not understand why you can't crash game once (if you really can't change it on go) and give single popup with "hey, we detected this app, it does some errors so we had to disable this setting, oki?" instead of those crashing shenanigans

commented

I've set an exclusion in RTSS for javaw.exe, but I still get the crash message that takes me to this GitHub issue.

Are we actually checking if RTSS is hooking into the game? If so, what is the mechanism?
If we are instead checking if the RTSS process simply exists, that isn't the right way because there are important things like software fan curves for graphics cards that those processes need to be running for.

commented

You guys borked something. Setting the use_no_error_g_l_context flag to true or to false changes nothing. I still crash with the RivaTuner warning message

commented

I never had this a single issue on 2 machines and tested 3 different nvidia driver versions from 2023, all with "Use No Error Context", MSI Afterburner + RTSS in autostart.

If the OGL flag and RTSS' overlay are mutually exclusive, how can my game even run (and without OGL errors)? O_o

image
(yes I have a javawmc.exe, just a hardlink, not related)

The game would have to be restarted in order to apply any kind of workaround.

Why not change the no error context setting and then crash the game with so the user can restart it?

commented

I've set an exclusion in RTSS for javaw.exe, but I still get the crash message that takes me to this GitHub issue.

Are we actually checking if RTSS is hooking into the game? If so, what is the mechanism? If we are instead checking if the RTSS process simply exists, that isn't the right way because there are important things like software fan curves for graphics cards that those processes need to be running for.

Not sure... it's checked here

For now, you can set the flag from the error it gives you -Dsodium.checks.win32.rtss=false until this is sorted.

commented

There's nothing wrong with the checks that Sodium is using. RivaTuner injects itself into everything and only conditionally decides to actually hijack the process. It's not possible for us to know whether or not RivaTuner is actually doing something, so we have to assume that the presence of the module is evidence of it doing so.

We have many reported issues (#2088, #2095, #2119, #2171...) and many more support threads on our Discord server which all demonstrate this problem. The only thing which fixed these problems was disabling RTSS, so that the module wasn't loaded into the game any longer.

commented

Just a correction: RTSS isn't useful to look at FPS, obviously, since there are a million of alternatives. But to cap framerates in a reliable way.

Therefore it's not the overlay the useful function, and crashing the whole thing regardless may simply be counterproductive.

Disabling the option "No Error Context" when you detect the program, or even show a warning screen would be much more logical and practical solutions.

commented

We can't disable the "No Error" bits once the context has been created. The game would have to be restarted in order to apply any kind of workaround. And waiting for the user to restart the game themselves, when their hard drive is being filled by logged errors, is not really an acceptable solution.

commented

Then forcefully crash after setting the option and restart with the workaround applied?

Making sure to add an explicit warning just in case someone goes switching the option back from the game, in case you cannot detect it at that time.

commented

I read whole thread and still not understand why you can't crash game once...

I'm not interested in permanently disabling features of the mod because the user happened to have some software running on their computer.

Even then, I'm under the impression that more than just the "No Error" context bits are interacting poorly with Rivatuner, based on other support threads we've seen. Graphics drivers do in fact change their behavior when a Compatibility context is requested, and that in turn can silently change the behavior of Sodium's rendering without us really knowing.

commented

RivaTuner injects itself into everything and only conditionally decides to actually hijack the process. It's not possible for us to know whether or not RivaTuner is actually doing something

It is possible for me to know, because I set the exclusions in RTSS running on my computer.
I understand the motive behind the decision taken, but there should at minimum at least be an option for the user to acknowledge and continue with a workaround. This workaround should also be discoverable from the crash popup.

commented

Then -Dsodium.checks.win32.rtss=false is enough for you and it is in the message. RTSS replaces the current OpenGL context right from under Sodium which causes severe issues. The only real solution is for RTSS to stop trying to hack legacy OpenGL into a modern OpenGL application which in itself reduces performance significantly.

commented
------------------------------------------------------------------------------------------------------------
READ ME! You appear to be using the RivaTuner Statistics Server (RTSS)!
  * Rivatuner will cause extreme performance issues when using Sodium, and it will likely fill up your hard drive
    with error logs.
  * You must fully disable (or uninstall) the RivaTuner Statistics Server.
    * If you don't remember installing RivaTuner, check to see if you have MSI Afterburner installed.
  * For more information on possible workarounds and alternatives to Rivatuner, see the following issue on GitHub:
    https://github.com/CaffeineMC/sodium-fabric/issues/2048
  * HINT: If you believe this is an error, then you can force the game to start anyways by adding the following JVM argument.
      -Dsodium.checks.win32.rtss=false
  * NOTE: We will not provide support for any issues caused by using this option. You are on your own!
------------------------------------------------------------------------------------------------------------

As has already been mentioned, the game crash does give important information on a) why this problem happens, b) what can be done about it, and c) how you bypass the checks.

We only use a JVM argument here (instead of an entry in the config file) to stop modpack authors from (easily) overriding the default. Doing so is almost always a bad idea if you're distributing Sodium alongside something else, since you cannot reasonably know the configuration of every computer the modpack is going to run on.

commented

How do you get that text though? My crash looks like this:
image
And the whole crash log does not contain that text, it just links to this issue

commented

It's in the log file, not the crash report file. Those log files will be in .minecraft/logs, usually as the latest.log file. The vanilla launcher only shows the crash report and the crash message.

commented

It seems like the problem here is not really our implementation, but rather the launcher not being helpful. I'm going to see about creating a wiki page on this repository, and change the URL mentioned in the crash message to point to the wiki with a full description of the problem.

commented

Yeah the message is not really user friendly and i like to think of myself as a pro user and not a dumb one.. Just swapping out the old message for the one you pasted earlier would be enough, even better if you could guide the user on how to set java arguments for the vanilla launcher

commented

There is now an entry for the RivaTuner issues in our wiki. We'll publish an update for Sodium in the upcoming days which changes the error message to link to this wiki page.

commented

OK, so as per usual, when we implement "workarounds" for things, it tends to really stir people up. Someone else, after hearing about these problems, was able to figure out more precisely what's causing the compatibility problem.

Summarily: The problems with Sodium only occur if RivaTuner 7.3.3 or older is being used. When using RivaTuner 7.3.4 (and newer?), it works correctly. The changelog actually mentions this:

Improved compatibility with OpenGL3+ applications, using overly restrictive debug checks in retail products and stopping rendering on any OpenGL errors (e.g. Defold Editor). Now RivaTuner Statistics Server uses different strategy instead of internal error interception for overlay renderer fallback from in-context rendering to separate context rendering.

So it seems like other applications were affected, and they just preferred to self-terminate rather than grinding to a halt like Minecraft does.

Anyways... this doesn't help us any. The authors of RivaTuner do not correctly include version information within the module they are injecting into the game, so we can't actually determine which version is installed. So the workaround is going to remain in Sodium until someone engineers a way to detect it, or until the authors of RivaTuner begin including version information.

commented

Sodium 0.5.5 at least includes better error diagnostics so that users receive a link to the wiki, with instructions on how to disable the check (if they must.)

commented

It seems the author of RTSS is not interested in doing the bare minimum to include a version string within the module they are injecting.

Their response is frustrating and utterly dismissive, for a number of reasons:

  • Windows already has a solution for this problem, and it's just to include the software version as part of the injected module. This avoids the need for anything to look into the registry or resort to other workarounds.
  • There is no documentation they make available for other developers. The README file mentions the existence of an environment variable to disable RivaTuner, but it's very recent, and the documentation doesn't bother to actually give you the name of the variable, so you're still stuck reverse engineering their software.
  • Developers should not have to read arbitrary application-specific keys out of the registry, nonetheless have to go searching for them. Even if this was somehow acceptable, there's no strong linkage between what the registry says and the actual files on disk, and we can't know that the module isn't being injected from other random third-party software that doesn't use the official installer.

Anyways, the solution we are now using to detect the RTSS version is relatively straight-forward, even if it's a huge pain to write in Java (due to the misery that is C/Winapi interop)...

  • Use GetModuleHandleExW to scan the process for known RTSS module names, and grab their handles.
  • Obtain the file name of the loaded RTSS module with GetModuleFileNameW and traverse up the directory structure to find the RTSS.exe executable.
  • Use GetFileVersionInfoInfoW to obtain the version information for the executable, and parse the resources to get the FileVersion or ProductVersion strings.
  • Parse the version string, and accordingly:
    • If you have version >= 7.3.4, then you don't need to do anything, as everything will just work normally.
    • If you have version >= 7.3.0, then set the environment variable RTSSHooksCompatibility=1 using SetEnvironmentVariableW and hope the author of RTSS believes you have a "valid use case" as to not ignore your program's attempts to modify it.
    • If you have an older version, just crash the game, because you can't do anything to workaround it.

Also, you will need to do the following things:

  • Use wglGetCurrentContext to record the OpenGL context handle, and compare it with the previously recorded value at the start of each frame.
  • If the context handle changes, assume that RTSS has hooked into your process, and scan for loaded modules again as described above.

If anyone else doing module injection reads this, please include a version string in your module. This should not take you more than 30 seconds and it saves other people a world of pain.