Skip to content

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

Merged
utkarshdalal merged 4 commits into
masterfrom
gamescope-payload-20261028-ion-redirect-daemon-copy
Oct 28, 2026
Merged

utkarshdalal merged 4 commits into
masterfrom
gamescope-payload-20261028-ion-redirect-daemon-copy

Conversation

@utkarshdalal

@utkarshdalal utkarshdalal commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

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:

This PR ships all three:

  • GamescopePayload.VERSION 20261027.1 -> 20261028.4. Payload 20261028.4 = 20261028.3 plus drm Attempted to add Vortek driver #29: lib/libgndrm_shim.so from drm master 7bb888d (#26 + Attempted to add Vortek driver #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 icd_shim: report the container's GPU identity like the X11 wrapper does 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. More fixes #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 + Attempted to add Vortek driver #29, built with NDK 27.3, llvm-strip --strip-unneeded; sha256 7e2c376b72425c680a33dd3cba2d7bca2098d201738f17535807725289a6e853, unstripped ddbe0f211387bd2c61872cd01f17f6ba0daf9168926426ff2efb72621a1e376c).
device build payload / daemon GL under gamescope
Galaxy Tab S7, Adreno 650, Android 11 Legacy shipped 20261027.1 black
Galaxy Tab S7 Legacy shim from #26 visible
Galaxy Tab S7 Legacy shipped payload + daemon from #28 visible (copied)
Galaxy Tab S7 Legacy this ICD + #26 shim (route27 payload), 4 runs visible, cube ~59 fps
Galaxy Tab S7 Legacy 20261028.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 14 Legacy this ICD + #26 shim visible, cube ~59 fps
Odin 3, Adreno 830 Modern Gravity Circuit 60 fps
Poco F6, Adreno 735, Android 14 Modern and Legacy shipped 20261027.1 visible (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.

…, daemon copies foreign buffers

OpenGL games were black with audio under gamescope on Snapdragon 865
devices: on kernels without dma-buf heaps Turnip allocates Xwayland's
window buffers through /dev/ion, which the preload shim did not redirect
into the daemon's AHardwareBuffer pool, so every frame was dropped.

Payload 20261028.1 is 20261027.1 with the gndrm shim from gamenative-drm
master (#26: ION allocations redirected like dma-heap ones). The daemon is
rebuilt from the same master (#28: a committed buffer the pool does not
own is copied into the pool instead of dropped, with an always-on log
line). Both verified on a Galaxy Tab S7 (Adreno 650, Android 11).
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6f04f1ab-4ffb-4a15-a90e-3b55962860e3
Commits

Reviewing files that changed from the base of the PR and between 4bc2bdd and 9c72abb.

Files ignored due to path filters: 1
  • app/src/main/jniLibs/arm64-v8a/libgamenative_drm.so is excluded by !**/*.so
Files selected for processing: 1
  • app/src/main/java/app/gamenative/display/GamescopePayload.kt

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Walkthrough

GamescopePayload.VERSION changes from 20261027.1 to 20261028.4. The version-dependent archive name and readiness check are unchanged.

Changes: Gamescope payload version

Layer / File(s) Summary
Update payload version
app/src/main/java/app/gamenative/display/GamescopePayload.kt
GamescopePayload.VERSION changes from 20261027.1 to 20261028.4.

Priority: Normal

Estimated code review effort: 1 (Trivial) | ~2 minutes

Change: Bug fix

Possibly related PRs

Suggested reviewers: joshuatam

Merge Risk: Minimal · up to 9c72a

This updates the bundled Gamescope payload version so devices fetch the newer archive. The archive was found available on both download endpoints with a matching checksum, so no merge-blocking risk remains.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the Gamescope payload version and the main technical changes related to ION allocations, foreign buffers, and the container's Turnip.
Description check Passed The description is detailed and covers the change rationale, testing results, change type, and checklist. The Recording section references screenshots in related DRM pull requests rather than includin…
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is detailed and covers the change rationale, testing results, change type, and checklist. The Recording section references screenshots in related DRM pull requests rather than including a recording or GIF directly, but the overall description is complete and relevant.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 1 files.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

View guided diff | Turn on auto-fix | Re-trigger cubic

…p on every flavor

Payload 20261028.2 adds the icd shim from gamenative-drm #27: the gamescope
process takes the same adrenotools-through-proxy route as the guests on
Legacy builds, as it already did on Modern ones. Verified on the Galaxy Tab
S7 (Adreno 650) and OnePlus 12R (Adreno 740) with the Legacy flavor.
@utkarshdalal utkarshdalal changed the title Gamescope payload 20261028.1: ION allocations reach the scan-out pool, daemon copies foreign buffers Gamescope payload 20261028.2: ION allocations reach the scan-out pool, daemon copies foreign buffers, gamescope on the container's Turnip Oct 28, 2026
The 20261028.2 archive carried the ICD shim built from gamenative-drm
master 7ed8285, which stalled the Galaxy Tab S7 (Adreno 650, Android 11)
five times out of five on App Live: wine's desktop process never finished
starting and no game window appeared. The same archive with the ICD from
e050ce4 passed there four times and on the OnePlus 12R. The only source
difference is gamenative-drm#25, the GPU identity override; it works on
the Odin 3 (Gravity Circuit 60 fps) but is not verified on Adreno 650, so
it stays out of this payload.

20261028.3 = 20261028.2 with lib/libadrenotools_gamescope.so replaced by
the e050ce4 build (sha256 d52b7ee4...), every other member identical.
Archive 14190262 B, sha256
dbce3c0ef9afef829a934ed2d204cbf7a4bdfc9ddfac6123e91667c25d296cad.
@utkarshdalal utkarshdalal changed the title Gamescope payload 20261028.2: ION allocations reach the scan-out pool, daemon copies foreign buffers, gamescope on the container's Turnip Gamescope payload 20261028.3: ION allocations reach the scan-out pool, daemon copies foreign buffers, gamescope on the container's Turnip Oct 28, 2026
… mode

Payload 20261028.4 is 20261028.3 with the gndrm shim from gamenative-drm
master 7bb888d (#29). The shim seeds gamescope's nested -w/-h size as the
scan-out geometry so length-only requests that arrive before the first
mode are matched, and resumes the daemon exchange on EINTR instead of
dropping the buffer. The ICD shim stays the e050ce4 build from .3.

The daemon is rebuilt from the same master: a length request also
matches a known geometry whose row-padded length equals it.

Shim sha256 22bd8624896c51e98bd0bbc7e99579546505d81b69763b62a3f24a8cca55c31b,
daemon (stripped) sha256 7e2c376b72425c680a33dd3cba2d7bca2098d201738f17535807725289a6e853,
archive 14191104 B sha256 ddd68fd9c486f2b45ab43318e165170ebd9c469676c7c476a0294685351dd0c7.

The same shim on the same base passed on a Galaxy Tab S7 (Adreno 650)
earlier today: cube ~59 fps, GL 12/12, every 1280x800 window buffer
mode-matched into the daemon pool, no foreign buffer copies.
@utkarshdalal utkarshdalal changed the title Gamescope payload 20261028.3: ION allocations reach the scan-out pool, daemon copies foreign buffers, gamescope on the container's Turnip Gamescope payload 20261028.4: ION allocations reach the scan-out pool, daemon copies foreign buffers, gamescope on the container's Turnip Oct 28, 2026
@utkarshdalal
utkarshdalal merged commit f8aa144 into master Oct 28, 2026
4 checks passed
@utkarshdalal
utkarshdalal deleted the gamescope-payload-20261028-ion-redirect-daemon-copy branch October 28, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant