icd_shim: report the container's GPU identity like the X11 wrapper does

Merged
UT
13d ago
+95-1

Problem

Under X11 the wrapper ICD replaces the GPU identity with the container's GPU name (WRAPPER_DEVICE_NAME / WRAPPER_DEVICE_ID / WRAPPER_VENDOR_ID, see ci-wrapper wrapper_physical_device.c). Under gamescope the shim passes the driver's own identity through, so the same container shows the game a different GPU on each display server.

With StevenMXZ's Turnip and TU_DEBUG=deck_emu, the raw identity is the Steam Deck (AMD Custom GPU 0405 (RADV VANGOGH), 0x1002/0x163f). NFS Hot Pursuit Remastered auto-detects its graphics preset from the adapter it sees: on that identity it writes Preset=4 (Ultra: shadows 4, textures 3, filtering 5, LODs 3, ambient occlusion 4, TAA) at 1920x1080 and then runs at 3-4 fps on the Odin 3. The GPU is saturated, not idle: the clock sits at its 1.05-1.1 GHz maximum while kgsl's busy counter reports 0 0, which is what that counter does when a job never lets it close a stats window; the HUD's "GPU 0 %" comes from the same counter. Under X11 the same container runs at 60 fps because the game never sees the AMD identity there.

Evidence on the Odin 3 (Turnip Gen8, gamescope):

  • First launch with the Adreno identity wrote Preset=-1 (shadows 1, AO 1, AA 1, LODs 0): races at 21-33 fps, GPU 98 % busy.
  • A launch with the Deck identity replaced that file with Preset=4 on its own (no settings touched) and ran 3.7 fps at Select Car.
  • With that Preset=4 file in place, the Adreno identity ALSO runs 3.7 fps at Select Car, same fence waits and present interval, so the settings file, not anything the game does differently per vendor, is what crawls. Runtime diff between the two identities: identical 74 loaded modules (no AMD-only library), identical DXVK feature/extension/swapchain set, identical DXGI and wine output; only the device name differs.
  • Most Wanted, Hades II and Celeste do not react to the AMD identity at all.

Fix

The shim applies the same override in vkGetPhysicalDeviceProperties and vkGetPhysicalDeviceProperties2: deviceName becomes Wrapper(<WRAPPER_DEVICE_NAME>), and deviceID and vendorID come from the env when they are set and > 0. Same rules as the wrapper. driverID stays the driver's own. Only guest processes get it: gamescope and Xwayland keep the real identity, because gamescope picks its RCAS shader layout from the vendor ID. The override is logged once (proxy: guest sees device ...). No new knobs.

Both display servers then show the game the same GPU, so a game that auto-detects its settings from the adapter picks the same preset on both, and switching display servers no longer looks like a new machine to EA's licence check.

Verification

  • Odin 3, Turnip Gen8 V34, deck_emu, gamescope: DXVK device line before Device : AMD VANGOGH, with this build Device : NVIDIA GeForce GTX 480 (the same as under X11).
  • Select Car fps with this build is not timed yet: EA's licence check refused the first launch with the NVIDIA identity ("Too many computers have accessed this account's version", then HTTP 403 CG_LIMIT_EXCEEDED). The number follows once the window resets.
  • Built for aarch64-linux-android; the unit test identity_follows_the_wrapper_env compiles for the Android target.