Skip to content

Fix/kgsl present wait fence - #96

Draft
KiralyCraft wants to merge 2 commits into
lfdevs:dev/adreno-mainfrom
KiralyCraft:fix/kgsl-present-wait-fence
Draft

Fix/kgsl present wait fence#96
KiralyCraft wants to merge 2 commits into
lfdevs:dev/adreno-mainfrom
KiralyCraft:fix/kgsl-present-wait-fence

Conversation

@KiralyCraft

@KiralyCraft KiralyCraft commented Aug 15, 2026

Copy link
Copy Markdown

A Codex assisted patch which attempts to fix reading buffers too early and causing flash-to-black issues in scenarios like Firefox GPU-enabled rendering, Minecraft, reVC and others.

I am not 100% sure what is going on here, but I can confirm this works on my Adreno 740 with KGSL with no significant performance drawbacks (-20% on glxgears compared to unfixed version: 1757 fps original vs 1337 with this patch).

This is accompanied by a fix to Termux:X11 where it does not correctly handle some callback disarming: KiralyCraft/termux-x11@fc534e5

EDIT: I do not completely trust what is going on here, but I can confirm it is reliable on my device. It might be better to rework this for better integration and style adaptation.

Keep deferred submit objects alive until KGSL has consumed their command lists and populated the shared kernel timestamp. This prevents BO teardown from freeing GPU addresses that the merged submission still references.
@lfdevs

lfdevs commented Aug 15, 2026

Copy link
Copy Markdown
Owner

In my testing with an Adreno 730 device, when the graphics API of Minecraft Java Edition is OpenGL, the version built by this PR fixes the game screen flickering issue compared to the version before modification. However, the scores of glmark2 and vkmark dropped significantly, so I will not merge this PR for the time being.

It is recommended to keep the PR status as "draft" so that people with similar needs can obtain the build artifacts more easily.

@KiralyCraft

KiralyCraft commented Aug 15, 2026

Copy link
Copy Markdown
Author

Should I investigate a solution which doesn't plummet the performance of glmark2 and vkmark ? Currently, correctness was a greater importance at the cost of performance

EDIT: This does not fix the artifacts in #44

@lfdevs

lfdevs commented Aug 15, 2026

Copy link
Copy Markdown
Owner

EDIT: This does not fix the artifacts in #44

Currently, it seems that the flickering issue is particularly severe on the Adreno 740, and I am unable to reproduce this issue on either Adreno 730 or 830.

@KiralyCraft

Copy link
Copy Markdown
Author

Just some more updates about the 740 situation. It seems he following now render correctly: Firefox with GPU acceleration, OpenXray, OpenMW, OpenJK, reVC and etLegacy (alongside of Minecraft). No more flickering, albeit performance is reduced. However, it seems to be better than the zink variant. I'll run some numbers when I get some more time.

@shakeheartbreak

Copy link
Copy Markdown

So I tried the #96 build artifact on an Adreno 740 (Termux:X11, Debian trixie proot)..

With it installed, my 32-bit OpenGL application running under box64 kills Termux:X11 within a few seconds under kgsl. logcat shows Scudo exhausting 33 size classes in sequence, from 48 bytes up to 131088, over about 7.4 seconds, in the LorieNative process - popped counts in the hundreds of thousands with pushed at zero, and rss 0K on every region.

Controls: the same application under zink is fine, glxgears and glmark2 under kgsl are also fine and the same application under kgsl on the unpatched 20260709 release produces no scudo output at all.

IIt' might be worth noting that 'm running stock Termux:X11, not the fc534e5 build. Is that commit required for #96 or should the Mesa half work standalone? Appreciate your help.

@KiralyCraft

KiralyCraft commented Aug 28, 2026

Copy link
Copy Markdown
Author

Yes, build fc534e5 in Termux:x11 fixes the issue where a Present wait fence callback remains registered after it fires. It is not simply an allocation leak. When the X server restarts its Sync trigger list scan, it can invoke the same callback repeatedly. Because that callback reexecutes and may requeue the same Present request for a future vblank while its fence remains alive, the request can be processed multiple times and eventually crash the X server. The patch unregisters the callback before reexecuting the Present request, making the callback execute only once.

I may be able to upload the necessary APK here if it would be easier for you; EDIT: Here it is, of a different commit but it contains the fix:
wrong-file-not-this-one.zip

@shakeheartbreak

Copy link
Copy Markdown

Superb reply and thank you. Your post explains the log better than a plain leak would - the allocation growth accelerated across 33 size classes in about 7 seconds rather than climbing steadily in one and every region reported rss 0K, which fits requests being duplicated rather than filled.

It also fits my controls: glxgears and glmark2 under kgsl were both fine on the same build and they presented at a steady cadence.

The APK is super helpful as I have no Android toolchain set up here. I'll reinstall the #96 Mesa build alongside it and report back on whether the crash goes away and what the artefacts do. Thanks again!

@shakeheartbreak

Copy link
Copy Markdown

A disappointing night's testing.. 😑

With the APK installed, alongside the #96 Mesa build, the crash was numerically identical to the stock Termux:X11 run: 33 Scudo OOM aborts across the same size classes, 1353 scudo lines and about 7 seconds from the first abort to the X server going down.

Both halves were verified before the run.. the installed base.apk hashes to the file you'd kindly uploaded (5171db856d00788452223b33538a5608) and glxinfo reported git-91f7e8c6f0.

My controls were left unchanged: zink is fine, glxgears and glmark2 under kgsl are fine and the unpatched 20260709 Mesa produces no scudo output at all with the same application.

So the multiplication doesn't appear to be the callback path fc534e5 fixes or there's a second route to it.

If you've got any ideas I can absolutely run anything that would narrow it down. I really thought this might fix it!

@KiralyCraft

Copy link
Copy Markdown
Author

Oops, I seem to have uploaded an experimental file then, and unfortunately it was the wrong APK. Your checksum confirmed that the attachment contained the prepatch backup, so your test never exercised the callback fix. I am sorry for wasting your testing time. Here is the corrected archive. Its ZIP MD5 is 707143af560e0b6639d39cd43800eace, and the APK inside should have MD5 04bf47a9794b123a379ef2b13b1a730a. Could you please repeat the same controlled test with this one?

termux-x11-universal-debug-0620f19-fixed.zip

@shakeheartbreak

Copy link
Copy Markdown

You've got absolutely nothing to apologise as far as I'm concerned. I'll download the new file, test it as soon as I can and then report back - thanks again for all your help.

@shakeheartbreak

Copy link
Copy Markdown

The corrected APK fixes it completely 😎

With your build (md5 04bf47a9794b123a379ef2b13b1a730a, verified against the installed base.apk) plus the #96 Mesa artifact (glxinfo: git-91f7e8c6f0), zero scudo lines and zero Scudo OOM aborts, against 1353 and 33 before. It ran the game code without crashes, compared to dying at seven seconds before.

The black corruption bands are gone too. Those are the artefacts in lfdevs #99. I'd partly assumed they were unrelated given #96 says it doesn't address #44.

Frame rate, 30-second sampled window on a fixed attract demo, Adreno 740: 52.58 fps silent, 47.38 with audio. My pre-#96 figures on the same scene were 54.4-56.6 and 47.0-47.8, so within noise on the configuration that matters.

The ~20% you measured on glxgears doesn't seem to transfer to this workload.

You've done some great work here!

@KiralyCraft
KiralyCraft force-pushed the fix/kgsl-present-wait-fence branch from 89da277 to 91f7e8c Compare September 2, 2026 03:25
@KiralyCraft

Copy link
Copy Markdown
Author

That's great news! I'm glad it works, since yours is now the first KGSL wait-fence done in the wild. I've also opened a PR for the Termux:X11 situation upstream, so that it will be included in future builds. It looks to me like the Termux side is an upstream bug from Xorg, so at least we'll have that one merged.

@shakeheartbreak

Copy link
Copy Markdown

Very happy to hear the Termux:X11 side is going upstream - I found termux/termux-x11#1114, so I'll follow that one. My own Termux:X11 build carries a small local patch, so knowing which tree it lands in is useful here.

One thing on 89da277 from reading it rather than running it - fd_bo_handle() now returns bo->funcs->kms_handle(bo) whenever the hook is present, and .kms_handle is registered unconditionally in kgsl_bo.c's bo_funcs. kgsl_bo_kms_handle() falls through to kgsl_bo_dmabuf(), which returns -1 unless the BO is KGSL_BO_IMPORT with a valid import_fd. So, for a shared BO that KGSL allocated itself, fd_bo_handle() returns 0 where it previously returned bo->handle. Neither FD_KGSL_USE_KMS_DUMB nor MESA_KGSL_X11_SHM_BRIDGE gates that. Is it meant to be unconditional?

Separately, if it's of any use to you: I can price the SHM bridge on a real workload. My case is a 2005 arcade game under box64 at 1280x720. It's around 780 draw calls per frame with 94% of the frame on the main thread and the GPU idle 69% of the time. A full-surface copy plus a synchronous round trip per frame all lands on that main thread, so glxgears will show almost nothing of what that path costs whereas mine will. A run-to-run spread on my bed is 0.70 fps, so the number would be a real one. I'd be happy to run it with the flag on and off if you'd want that and it'd benefit me too.

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.

3 participants