Gamescope payload 20261028.4: ION allocations reach the scan-out pool, daemon copies foreign buffers, gamescope on the container's Turnip

Merged
UT
13d ago
+1-1

Description

OpenGL games (Gravity Circuit, LÖVE2D) showed a black screen with audio under gamescope on Snapdragon 865 devices (Retroid Pocket Flip 2, Galaxy Tab S7; Adreno 650) while DXVK games rendered. Reported by RAHBOOTS in the v1.4.0 release-preview thread.

Under gamescope a zink guest renders through Xwayland's window buffers. On kernels without dma-buf heaps (4.19 class) Turnip allocates those through /dev/ion; the preload shim only redirected dma-heap allocations into the daemon's AHardwareBuffer pool, so the window buffers were unknown to the daemon and every frame was dropped. Three gamenative-drm changes fix it, all verified on a Galaxy Tab S7 (SM-T875, Android 11, dma_heap_system=false ion=true) with the wrapper test's GL window held on screen under gamescope:

  • GameNative/gamenative-drm#26: the shim redirects ION_IOC_NEW_ALLOC the same way. Shipped payload: black, no redirect lines. Fixed shim: window visible, every 1280x800 Xwayland buffer heap alloc 4096000 B -> daemon buffer.
  • GameNative/gamenative-drm#28: the daemon copies any committed buffer it does not own into the pool instead of dropping it, with an always-on first-sight log line. Tested alone with the shipped shim: window visible, foreign dma-buf summary: copied_frames=2466 buffers=28 failures=0.
  • GameNative/gamenative-drm#29: scan-out buffers requested by length before the first mode. The shim seeds gamescope's nested -w/-h size as the scan-out geometry so Xwayland's 1280x800 window buffers are matched before any ADDFB2, and it resumes the daemon exchange on EINTR instead of dropping the buffer; the daemon also matches a length against a known geometry with row-padded pitch. Without it a few window buffers still fell back to plain ION allocations and reached the daemon only through the #28 copy. Tab S7 with this shim: cube ~59 fps exit 0, GL 12/12, 17/17 1280x800 buffers mode-matched 1280x800 -> daemon buffer, zero foreign-buffer lines.

This PR ships all three:

  • GamescopePayload.VERSION 20261027.1 -> 20261028.4. Payload 20261028.4 = 20261028.3 plus drm #29: lib/libgndrm_shim.so from drm master 7bb888d (#26 + #29, sha256 22bd8624896c51e98bd0bbc7e99579546505d81b69763b62a3f24a8cca55c31b); this exact shim on this exact base passed on the Tab S7 earlier today. Everything else as in 20261028.3: lib/libadrenotools_gamescope.so from drm e050ce4 (#27 gamescope driver route on top of #26/#28; sha256 d52b7ee489475cd42a3f21699dd498577f6ccaacaaa858228d104be7e0412f89); every other file identical to 20261027.1. Archive 14191104 B, sha256 ddd68fd9c486f2b45ab43318e165170ebd9c469676c7c476a0294685351dd0c7 (exactly one member differs from 20261028.3, sha256 dbce3c0ef9afef829a934ed2d204cbf7a4bdfc9ddfac6123e91667c25d296cad), served from downloads.gamenative.app and the R2 fallback.
  • Not 20261028.1: that name was taken by a payload uploaded at 07:53 UTC today whose preload shim is the old build without the ION redirect.
  • Not 20261028.2: its ICD shim was built from drm master 7ed8285, which adds GameNative/gamenative-drm#25 (GPU identity override). That archive stalled the Tab S7 five times out of five on App Live (wine's desktop process never finished starting, no game window), while the same archive with the e050ce4 ICD passed four times there and on the OnePlus 12R. #25 runs fine on the Odin 3 (Gravity Circuit, 60 fps, swapped in place) but is not verified on Adreno 650, so it stays out of this payload until it is.
  • jniLibs/arm64-v8a/libgamenative_drm.so from drm master 7bb888d (#28 + #29, built with NDK 27.3, llvm-strip --strip-unneeded; sha256 7e2c376b72425c680a33dd3cba2d7bca2098d201738f17535807725289a6e853, unstripped ddbe0f211387bd2c61872cd01f17f6ba0daf9168926426ff2efb72621a1e376c).
devicebuildpayload / daemonGL under gamescope
Galaxy Tab S7, Adreno 650, Android 11Legacyshipped 20261027.1black
Galaxy Tab S7Legacyshim from #26visible
Galaxy Tab S7Legacyshipped payload + daemon from #28visible (copied)
Galaxy Tab S7Legacythis ICD + #26 shim (route27 payload), 4 runsvisible, cube ~59 fps
Galaxy Tab S7Legacy20261028.4 contents: this ICD + #29 shim + #29 daemon (pre-review build)visible, cube ~59 fps, GL 12/12, no foreign copies
OnePlus 12R, Adreno 740, Android 14Legacythis ICD + #26 shimvisible, cube ~59 fps
Odin 3, Adreno 830ModernGravity Circuit60 fps
Poco F6, Adreno 735, Android 14Modern and Legacyshipped 20261027.1visible (dma-heap kernel, unaffected)

Also in the payload: GameNative/gamenative-drm#27, the gamescope process runs on the container's adrenotools Turnip through the proxy on Legacy builds as it already did on Modern ones. Legacy regression on the Tab S7 (Adreno 650) and OnePlus 12R (Adreno 740): cube ~59 fps exit 0, GL 12/12 visible, gamescope driver line shows the adrenotools build on both.

Recording

Screenshots in the drm PRs: Tab S7 GL window black on the shipped payload and colour-cycling with the fix.

Type of Change

  • Bug fix
  • Performance / stability improvement
  • Compatibility improvements
  • Other (requires prior approval)

Checklist

  • If I have access to #code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed.
  • This change aligns with the current project scope (core functionality, stability, or performance). If not, it has been explicitly approved beforehand.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Summary by CodeRabbit

  • Updates
    • Updated the Gamescope version used by the app. This update changes the version identifier; the version-dependent archive naming and readiness checks remain unchanged. No other user-facing changes are included in this update.