NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.49k stars 13.68k forks source link

Steam games fail to start with "Couldn't find matching GLX visual" #106503

Closed flisk closed 3 years ago

flisk commented 3 years ago

Describe the bug Attempting to start TF2 through Steam currently yields an error popup:

Failed to create SDL window: Couldn't find matching GLX visual

Additional context This issue has been previously reported on Valve's Source 1 games issue tracker: https://github.com/ValveSoftware/Source-1-Games/issues/3455

Notify maintainers @jagajaga

Metadata

 - system: `"x86_64-linux"`
 - host os: `Linux 5.4.81, NixOS, 20.09.2190.78dc359abf8 (Nightingale)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.3.9`
 - channels(root): `"nixos-20.09.2190.78dc359abf8, nixos-unstable-21.03pre257780.e9158eca70a"`
 - channels(tobias): `"nixos-unstable-21.03pre255600.24eb3f87fc6"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
jasonwhite commented 3 years ago

I have the same exact problem after the most recent Steam update (or was it a TF2 update?). Suspecting that it is probably failing to load some file from the Nix store, I ran Steam with:

$ strace -f -e trace=%file steam 2> steam.log

Poking through the (huge) log looking for ENOENT errors, I discovered several failures to find either libGLX_nvidia.so.0 or libGLX_indirect.so.0:

[...snip...]
[pid 11180] openat(AT_FDCWD, "/nix/store/7943wlbwhlmkcwmcgclvnf3y0y287j47-glibc-2.30/lib/libGLX_nvidia.so.0", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[...snip...]
[pid 11180] openat(AT_FDCWD, "/nix/store/7943wlbwhlmkcwmcgclvnf3y0y287j47-glibc-2.30/lib/libGLX_indirect.so.0", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[...snip...]

Obviously, glibc doesn't contain libGLX_*.so.0, but that's the last location on the search path.

Oddly, Steam itself finds libGLX_nvidia.so.0 just fine in /run/opengl-driver/lib, but the TF2 executable doesn't. TF2 is a 32-bit binary, so it should really be looking in /run/opengl-driver-32/lib. There's probably a problem with the TF2 game RPATH that prevents it from searching in /run/opengl-driver-32/lib. I suspect Valve inadvertently changed something in the build process that removed this from the RPATH.

Setting LD_LIBRARY_PATH=/run/opengl-driver-32/lib before opening steam didn't seem to help. (Does Steam not let games inherit environment variables?)

Here's a hacky workaround that I used to verify this is the issue:

  1. In a text editor, open up ~/.local/.local/share/Steam/steamapps/common/Team Fortress 2/hl2.sh.
  2. Prepend LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/run/opengl-driver-32/lib" to ${GAME_DEBUGGER} "${GAMEROOT}"/${GAMEEXE} "$@"
  3. Launch the game. No need to restart Steam.

(Disclaimer: Since this is editing game files, it might lead to triggering VAC, but I don't really know for sure. I guess I'll find out!)

So far it looks like the ball is in Valve's court to fix this, although maybe NixOS could employ a less hacky workaround.

Technical27 commented 3 years ago

A better fix is to right-click on the game, go to properties, and put LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/run/opengl-driver-32/lib" %command% in the launch options. Its a steam issue since it only started to happen to me when steam updated and not with any system updates.

nyanloutre commented 3 years ago

This issue is also affecting all proton games, adding "/run/opengl-driver/lib:/run/opengl-driver-32/lib" fixes everything

jbalme commented 3 years ago

Setting LD_LIBRARY_PATH=/run/opengl-driver-32/lib before opening steam didn't seem to help. (Does Steam not let games inherit environment variables?)

Nix runs Steam in a FHS environment, and I'm not sure if that passes through. I'll tinker with it in a bit.

jerryaldrichiii commented 3 years ago

Setting the following Steam launch options (Properties -> GENERAL -> SET LAUNCH OPTIONS) makes this work for me on NixOS:

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/run/opengl-driver/lib:/run/opengl-driver-32/lib" %command%

Thanks @jbalme and @nyanloutre

ThibaultLemaire commented 3 years ago

As this is not limited to TF2, I think we should change the title.

I have the issue with every game in my library that relies on Steam's libraries (whether through proton or not) since 2020-12-08 when Steam rolled out its update. And I can confirm @jerryaldrichiii's workaround is working for all of them.

PaxSov commented 3 years ago

@jerryaldrichiii workaround is working perfectly for me. I have not gotten VAC banned as of now.

flisk commented 3 years ago

I haven't seen this issue occur with any games other than TF2 personally, but since that doesn't seem to apply for everyone, I've changed the title accordingly.

jbalme commented 3 years ago

Did some snooping around.

Putting echo $LD_LIBRARY_PATH > /tmp/foo; echo %command% in Launch Options for a game results in a /tmp/foo containing:

/lib32:/lib64:/steamrt/amd64/lib/x86_64-linux-gnu:/steamrt/amd64/lib:/steamrt/amd64/usr/lib/x86_64-linux-gnu:/steamrt/amd64/usr/lib:/steamrt/i386/lib/i386-linux-gnu:/steamrt/i386/lib:/steamrt/i386/usr/lib/i386-linux-gnu:/steamrt/i386/usr/lib

Running echo $LD_LIBRARY_PATH in steam-run sh results in:

/lib32:/lib64:/steamrt/amd64/lib/x86_64-linux-gnu:/steamrt/amd64/lib:/steamrt/amd64/usr/lib/x86_64-linux-gnu:/steamrt/amd64/usr/lib:/steamrt/i386/lib/i386-linux-gnu:/steamrt/i386/lib:/steamrt/i386/usr/lib/i386-linux-gnu:/steamrt/i386/usr/lib${LD_LIBRARY_PATH:+:}/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32

It seems Nix's FHS wrapper is already putting the OpenGL drivers in the $LD_LIBRARY_PATH for us, but it looks like a possible escaping issue which Steam is now not handling well? It cuts off the path right at the $ which is before the drivers appear in the path.

jbalme commented 3 years ago

This seems to be the source of the problem:

https://github.com/NixOS/nixpkgs/blob/6a4be92dd86dd589dd5c52145d7fe34353af8479/pkgs/games/steam/fhsenv.nix#L51

kevincox commented 3 years ago

This also fixes Left 4 Dead 2 for me.

jbalme commented 3 years ago

Tried building Steam with that line changed, and it seems to be a dead end, and Steam is doing something more with LD_LIBRARY_PATH.

glasserc commented 3 years ago

Using the workaround also fixed Don't Starve Together, which broke on the same update, and also Frozen Synapse, which has been broken for a while.

jbalme commented 3 years ago

Found another possible lead:

In steam.sh, when STEAM_RUNTIME is set, the LD_LIBRARY_PATH is replaced by the Runtime's generated paths. In previous versions of steam.sh, the Runtime's paths were instead prepended.

Unfortunately, trying to modify steam.sh results in it being replaced on next run.

As Nix ships it's own Steam Runtime, it could be modified to add the paths to the graphics drivers.

jbalme commented 3 years ago

That did it, I'll have a patch in a bit.

jbalme commented 3 years ago

NIXPKGS_ALLOW_UNFREE=1 nix-env -f https://github.com/jbalme/nixpkgs/archive/steam-fix.zip -iA steam for the impatient

nixos-discourse commented 3 years ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/i-cannot-run-l4d2-nor-portal/9982/16