ValveSoftware / steam-runtime

A runtime environment for Steam applications
Other
1.17k stars 86 forks source link

Using Vulkan in a Steam Runtime 3 (sniper) toolbox container fails with error message "Found no drivers!" #678

Closed tillmann closed 1 month ago

tillmann commented 1 month ago

Your system information

Please describe your issue in as much detail as possible:

Using Vulkan in a Steam Runtime 3 (sniper) toolbox container fails with error message "Found no drivers!"

I create and enter a toolbx container like this:

podman pull registry.gitlab.steamos.cloud/steamrt/sniper/sdk
toolbox create -i registry.gitlab.steamos.cloud/steamrt/sniper/sdk sniper
toolbox enter sniper

I want to use Vulkan inside the container. To do a sanity check, I run vulkaninfo. I expect valid output similar to running (on the host)

flatpak install org.freedesktop.Platform.VulkanInfo
flatpak run org.freedesktop.Platform.VulkanInfo

(Output in this Gist)

However, if I run vulkaninfo inside the toolbx-container above, I get the following:

ERROR: [Loader Message] Code 0 : vkCreateInstance: Found no drivers!
Cannot create Vulkan instance.
This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU that does not support Vulkan.
ERROR at ./vulkaninfo/vulkaninfo.h:674:vkCreateInstance failed with ERROR_INCOMPATIBLE_DRIVER

I tried installing mesa-vulkan-drivers and rerun vulkaninfo inside the toolbx-container which gives the following:

WARNING: [Loader Message] Code 0 : loader_scanned_icd_add: Driver /usr/lib/x86_64-linux-gnu/libvulkan_intel.so supports Vulkan 1.2, but only supports loader interface version 4. Interface version 5 or newer required to support this version of Vulkan (Policy #LDP_DRIVER_7)
WARNING: [Loader Message] Code 0 : loader_scanned_icd_add: Driver /usr/lib/x86_64-linux-gnu/libvulkan_lvp.so supports Vulkan 1.1, but only supports loader interface version 1. Interface version 5 or newer required to support this version of Vulkan (Policy #LDP_DRIVER_7)
WARNING: [Loader Message] Code 0 : loader_scanned_icd_add: Driver /usr/lib/x86_64-linux-gnu/libvulkan_radeon.so supports Vulkan 1.2, but only supports loader interface version 4. Interface version 5 or newer required to support this version of Vulkan (Policy #LDP_DRIVER_7)
WARNING: [Loader Message] Code 0 : Layer VK_LAYER_MESA_device_select uses API version 1.2 which is older than the application specified API version of 1.3. May cause issues.
WARNING: [Loader Message] Code 0 : terminator_CreateInstance: Driver /usr/lib/x86_64-linux-gnu/libvulkan_lvp.so supports interface version 1 but still exposes VkSurfaceKHR create/destroy entrypoints (Policy #LDP_DRIVER_8)
amdgpu: unknown (family_id, chip_external_rev): (148, 10)
ERROR: [Loader Message] Code 0 : setup_loader_term_phys_devs:  Call to ICD 0's 'vkEnumeratePhysicalDevices' failed with error 0xfffffffd
ERROR at ./vulkaninfo/vulkaninfo.h:237:vkEnumeratePhysicalDevices failed with ERROR_INITIALIZATION_FAILED

This feels like a major corner-case to me, but I also expected it to "just work"™. Is sniper simply too old for my gpu? If I wanted to adopt a container-centric linux-first development-environment do develop a game targeted to steam/steamdeck, would there be a more promising approach?

Steps for reproducing this issue:

  1. Have podman and toolbx installed and possibly a fairly new gpu
  2. podman pull registry.gitlab.steamos.cloud/steamrt/sniper/sdk
  3. toolbox create -i registry.gitlab.steamos.cloud/steamrt/sniper/sdk sniper
  4. toolbox enter sniper
  5. vulkaninfo
tillmann commented 1 month ago

I think I just answered parts of my question. Running my baseline check using flatpak on (the oldest) branch 20.08 of org.freedesktop.Platform.VulkanInfo gives the exact same error message.

The question for the more promising approach remains, would I have to wait for medic? A pointer towards a sensible approach would be much appreciated :)

smcv commented 1 month ago

The SDK OCI image is intended for compiling your game, but not really for running it. Similarly, the Platform OCI image can be suitable for automated tests, dedicated servers and similar purposes, but OpenGL will generally be software-only, and Vulkan won't generally work.

Both OCI images provide a strict, lowest-common-denominator environment where all libraries are at the oldest version that can be guaranteed to be present, which in most cases means whatever version was available in Debian 11 (2021). The graphics drivers are also from 2021, which is presumably why they don't support your newer GPU.

Typically Docker or Podman will also not give you access to the device nodes required to access your GPU, although perhaps Toolbx does give you that access by default (I haven't experimented with this).

When the sniper runtime is used by end users as part of the Steam Linux Runtime 3.0 (sniper) compatibility layer, the environment that it runs in is a composite of the application libraries from sniper and the graphics drivers from the user's host system (often much newer), with the graphics drivers' dependencies (glibc, libdrm, etc.) taken from either sniper or the host system, whichever is newer. For example, in your case, the host system is Fedora, which has a much-newer-than-2021 version of amdgpu that (presumably) does support your GPU.

To test your game in a realistic end-user environment, you'll need to use the same mechanisms that Steam does: https://gitlab.steamos.cloud/steamrt/sniper/sdk#testing-software-that-runs-in-sniper

Or to test outside Steam (which obviously is not something that is 100% supported by Valve/Steam, but could be useful during early development), you can download a copy of the SLR 3.0 (sniper) container files and use a command like /path/to/SteamLinuxRuntime_sniper/run -- ./your-game. I'm not sure whether this will work as-is on an image-based OS like Silverblue, because it requires a 32-bit glibc and graphics drivers installed on the host system, and I don't know whether Silverblue has those - but it might work anyway if your game happens to be fully 64-bit.

Is sniper simply too old for my gpu?

Yes if you use a "pure" sniper environment like Docker/Podman/Toolbx, but on end-user systems we use it in a way that bypasses that.

If I wanted to adopt a container-centric linux-first development-environment do develop a game targeted to steam/steamdeck, would there be a more promising approach?

What I would recommend is: compile in sniper Docker/Podman/Toolbx environment, but test in SLR 3.0 via Steam, which will borrow the graphics drivers from whatever your host OS happens to be. When your game is far enough into development to make it worthwhile, also test on a Steam Deck, because there's no substitute for testing on your actual target platform.

Because the graphics drivers come from the host OS, when you get closer to release, I expect that you will also want to choose a non-rolling-release minimal OS to target (I would suggest Ubuntu LTS, Debian stable or RHEL/CentOS, possibly an older-than-current branch like Ubuntu 22.04) and test on that minimal OS version, so that you have a milestone version that you can use as the minimum in your game's system requirements.

The Steam Deck uses a rolling-release operating system, so it is generally only a few weeks or months old, but that makes it difficult to say what your minimum requirements are, and difficult to know whether users of non-rolling-release distros can expect to be able to run your game successfully or not.

smcv commented 1 month ago

https://partner.steamgames.com/doc/steamdeck/loadgames describes a recommended way to test games on Deck.

tillmann commented 1 month ago

Thanks a bunch! Great clarification. That's way more than I could have asked for!

I'll just close this. :+1: