icd_shim: route the gamescope process through the same Adreno driver path as guests

Merged
UT
13d ago
+39-48

Draft: a behaviour change for Legacy builds, found while chasing the Adreno 650 black screen (GameNative/gamenative-drm#26 is the fix for that; this is not).

What differs between the app flavors today. init_once gives the gamescope process the payload's bundled libvulkan_freedreno.so (Mesa 26.2.3) when /proc/self/comm contains "gamescope", and every other process the user's adrenotools driver through the WSI proxy. The Legacy flavor (targetSdk 28, Android 13 and below) execs gamescope directly, so comm is "gamescope" and that branch is taken: gamescope on the bundled driver, Xwayland and the game on the adrenotools driver. The Modern flavor runs everything through /system/bin/linker64, so comm is "linker64", the name check misses, and gamescope takes the guest route too: the same adrenotools driver, through the proxy. All Adreno gamescope verification so far (Odin 3, OnePlus 12R, Poco F6) ran on Modern builds, so the mixed route is the untested one. Logs: Legacy gn-vkshim: ICD loaded ... comm=gamescope then vulkan: limits: ... driverVersion=0x06802003 driverInfo="Mesa 26.2.3"; Modern comm=linker64, using adrenotools driver libvulkan_freedreno.so via WSI proxy, driver 0x6863063.

Change. Drop the gamescope-only branch so the gamescope process takes the same route as the guests on both flavors: adrenotools through the proxy when ADRENOTOOLS_DRIVER_PATH is set, the system driver step still excluded for gamescope and Xwayland, the payload freedreno as the last fallback. Module header updated; the old comm-only integration test replaced by two covering the new rule.

Verified so far. cargo check for aarch64-linux-android clean; 57 unit and 13 integration tests pass in a rust:1-bookworm container (one pre-existing test needs a warm build directory). On the Poco F6 (Adreno 735) with the Legacy build and the mixed route, Gravity Circuit renders, so the mixed route is not broken on a7xx; this PR removes the flavor difference rather than fixing a known failure.

Needs before merge. A Legacy-build regression on an Adreno device under gamescope (the Tab S7 on App Live, or a Legacy install on the Poco F6), and a decision on whether the bundled-driver route for gamescope was wanted for a reason that is no longer written down. Kept as a draft until then.

Legacy regression (2026-10-28, rebased on master bc95c72, payload browserstack/gamescope-route27-e050ce4-base20261027.1.tzst = 20261027.1 base + this ICD shim + the #26 preload shim, master daemon, Legacy testbed flavor so gamescope is exec'd directly, comm=gamescope):

devicegamescope driver lineTestD3D cube under gamescopewrapper test gl/ under gamescope, window held 60 s
Galaxy Tab S7, Adreno 650, Android 11 (ION kernel)device="Turnip Adreno (TM) 650" api=1.3.350 driverVersion=0x06801063 driverName="Turnip" (adrenotools R4; the bundled build would read 0x06802003 "Mesa 26.2.3")first frames at 127 s (cold prefix), steady 58.9-59.4 fps, exit 0, 144 pipelines ok12/12 pass, window visible, scanout redirect lines present, atomic commits ok=3305 fail=0
OnePlus 12R, Adreno 740, Android 14 (dma-heap kernel)device="Turnip Adreno (TM) 740" api=1.4.350 driverVersion=0x06801063 driverName="Turnip"steady 59.4-59.7 fps, exit 0, 144 pipelines ok12/12 pass, window visible

No rejects compute, VK_ERROR, Fatal or precompile failures on either device. The only error lines are the usual teardown drmModeRmFB failed: Bad file descriptor after the reaper ends the session.

Seen on both devices and unrelated to this PR: the daemon declines the first few length-only scan-out requests with errno 22 (before it knows the mode), so one early buffer per phase is carried by the #28 copy path (copied into pool, failures=0) instead of the zero-copy route.