Post

Just Some Annoying Linux Thing

Introduction

Ahh, Linux desktop UX.

I’m messing about with Godot, the Open Source game engine, but want to use the Linux version.

The general recommendation knocking around the internet is to download directly from the Godot website, not to deploy the flatpak version or the one in Ubuntu’s software repositories because those are usually out of date (plus ca change). Anyway, I download the archive, unzip it and fire up Godot from the terminal.

Part 1: Ignoring the Graphics Card

At first glance it seems to start fine, but my eagle-eye spots a problem just before it’s hidden by the Godot project window.

1
2
3
4
Godot Engine v4.3.stable.mono.official.77dcf97d8 - https://godotengine.org
glx: failed to create dri3 screen
failed to load driver: nouveau
OpenGL API 4.6 (Core Profile) Mesa 24.0.3-1pop1~1711635559~22.04~7a9f319 - Compatibility - Using Device: Intel - Mesa Intel(R) UHD Graphics (TGL GT1)

Two typically laconic errors but, somewhat more unnerving, why is Godot using Intel integrated graphics when it can offload them to a perfectly good NVIDIA GeForce RTX 3050 card installed in my laptop? I suspect it’s all related.

To start with I double-check NVIDIA drivers are installed. They are. I open the NVIDIA Settings Panel and check that it recognises the card, which it does. It even tells me the card is running at a temperature of 61c, which seems a little toasty considering it’s currently being asked to do absolutely nothing. I even start Steam and run a game while watching the GPU Utilisation metric in the same panel and it’s definitely being used, so there’s no issue with the card itself. What’s Godot’s problem?

Taking those two errors one at a time.

1
glx: failed to create dri3 screen

After a bit of Googling and some forum hopping I find that GLX is an OpenSource library enabling Linux software direct access to GPU hardware via something else called DRI3. It’s kind of the Linux (and, therefore open-source) version of DirectX. DRI3 refers to Direct Rendering Infrastructure Version 3 which is, basically, the Linux graphics framework. They both sound similar, but I believe that Godot makes calls into the GLX library which makes called into DRI3, which talks to your graphics card through its driver.

So it looks like Godot tried to initialise a new screen buffer using a GLX API call, but this failed because the underlying DRI3 framework refused to service the request, probably due to the next error.

1
failed to load driver: nouveau

Apparently, Nouveau is the name of the OpenSource NVIDIA card driver that ships with Ubuntu (from Freedesktop.org). Ubuntu will not ship proprietary drivers, presumably because that breaches FOSS principles, but NVIDIA do now distribute drivers for Linux and I run POP OS which will install these drivers if it finds an NVIDIA card. Consequently, Nouveau is not on my system.

My conclusion, then, however wonky, is that Godot is aware I have an NVIDIA card but has assumed I’m using the Ubuntu Nouveau drivers and tried to initialise them. The DRI3 cannot find the drivers so it spits out the above error and Godot switches to the Intel Onboard Graphics hardware which is perfectly serviceable for my Godot tinkering, but I’d rather use the graphics card I paid for.

Part 2: The Graphics Card who came in from the Cold

Basically, I have to pass two environment variables to the executable when I run it through the terminal.

1
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia ./godot

Although there’s no explanation of these specific environment variables that I can find, my best interpretation is that the first is an instruction to offload rendering to the graphics card by setting the value to 1, and the second is pointing out the name of the driver to use. Why I need to specify all this, I’m not sure. I’m assuming it’s some power-saving thing.

..And I can see, finally, that Godot has deigned to use the NVIDIA card.

1
2
Godot Engine v4.3.stable.mono.official.77dcf97d8 - https://godotengine.org
OpenGL API 3.3.0 NVIDIA 560.35.03 - Compatibility - Using Device: NVIDIA - NVIDIA GeForce RTX 3050 Ti Laptop GPU

Of course, one could argue whether there was any point in going through all this, but, as I said earlier, I paid for the damn card and it’s going to render my shitty pixel art whether it wants to or not.

Part 3: Pretty Little Pictures

I don’t want to have to load Godot from the terminal each time, I want a nice little icon on my favourites bar that I can click on, ao, onto the next problem.

I have to create the information for a nice icon myself. It’s stored in the helpfully named: ~/.local/shared/applications.

1
2
3
4
5
[Desktop Entry]
Name=Godot
Type=Application
Exec=env __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia ~/Software/godot/godot
Icon=~/.local/share/applications/icon_color.svg

Hang on, this doesn’t work because the launcher can’t expand the ~ home shortcut. So I have to replace it with this.

1
2
3
4
5
[Desktop Entry]
Name=Godot
Type=Application
Exec=env __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia /home/cakers/Software/godot/godot
Icon=/home/cakers/.local/share/applications/icon_color.svg

Right. What’s next?

Part 4: Firing it up!

We launch Godot and all seems good. When I execute the default project, I get:

1
2
Godot Engine v4.3.stable.mono.official.77dcf97d8 - https://godotengine.org
Vulkan 1.3.280 - Forward Mobile - Using Device #1: NVIDIA - NVIDIA GeForce RTX 3050 Ti Laptop GPU

Fine. Whoopee … Are we done?

No. Now when I try to add a C# script to the project, I get a ‘Cannot create C# Solution’ error, and the following text in the syslog:.

1
2
3
4
5
Dec  4 09:29:07 pop-os godot.desktop[19840]: ERROR: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
Dec  4 09:29:07 pop-os godot.desktop[19840]: File name: 'Microsoft.Build, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Dec  4 09:29:07 pop-os godot.desktop[19840]:    at GodotTools.ProjectEditor.ProjectGenerator.GenAndSaveGameProject(String dir, String name)
Dec  4 09:29:07 pop-os godot.desktop[19840]:    at GodotTools.CsProjOperations.GenerateGameProject(String dir, String name) in /root/godot/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs:line 13
Dec  4 09:29:07 pop-os godot.desktop[19840]:    at: string GodotTools.CsProjOperations.GenerateGameProject(string, string) (/root/godot/modules/mono/editor/GodotTools/GodotTools/CsProjOperations.cs:13)

A quick google confirmed Version 15.1.0.0 is the .NET V8 Core SDK, the one Godot requires. I installed this earlier as it’s in the pre-requsites for Godot. Honest, I did. Look!

1
2
➜ dotnet --version
8.0.404

Furthermore, if I run godot from my terminal, using the command line above it works fine. It’s only when I run it from my shiny new desktop icon.

The issue is my user env vars are in my session only and are not transferred when running from the icon.

So, I have to add the DOTNET environment variables to the command line.

1
Exec=env DOTNET_ROOT=/home/cakers/.dotnet PATH=$PATH:$DOTNET_ROOT:DOTNET_ROOT/tools __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia /home/cakers/Software/godot/godot

…And try again.

It still doesn’t work, same error.

So, last gasp and to stop blood pressure from getting any higher, I’ll try creating an sh script to launch Godot and have the desktop file call that instead of running the executable directly.

1
2
3
4
5
6
#!/bin/sh
export DOTNET_ROOT=/home/cakers/.dotnet
export PATH=$PATH:$DOTNET_ROOT:DOTNET_ROOT/tools
export __NV_PRIME_RENDER_OFFLOAD=1
export __GLX_VENDOR_LIBRARY_NAME=nvidia
exec /home/cakers/Software/godot/godot

FINALLY …. just …. FINALLY! I can actually load Godot from my favourites bar and it will use the NVIDIA graphics driver and let me use C#.

…But now it’s late and I have work in the morning, so no Godot this evening.

Epilogue

A couple of years ago Fabian Sanglard wrote a great article about spending an entire evening trying to get his new external SSD drive to work with Linux https://fabiensanglard.net/a_linux_evening/index.html and only able to do so once he’d found a single response on an old forum post that was referring to a slightly different issue. My problem is not nearly as technical as his, but the frustrations are similar.

It’s one of those things with Linux - You often end up down rabbit holes shaving yaks.

This post is licensed under CC BY 4.0 by the author.