Skip to content

Android/GLES port: GLES 3.2 compute backend, shader int/uint strictness, AYN Thor dual-screen wiring - #19

Open
aabrole wants to merge 12 commits into
RetroPortingToolKit:mainfrom
aabrole:thor-android-port
Open

Android/GLES port: GLES 3.2 compute backend, shader int/uint strictness, AYN Thor dual-screen wiring#19
aabrole wants to merge 12 commits into
RetroPortingToolKit:mainfrom
aabrole:thor-android-port

Conversation

@aabrole

@aabrole aabrole commented Sep 5, 2026

Copy link
Copy Markdown

Android / AYN Thor port of the runner

This is the working Android arm64 port behind Hunters Recomp, the MPH build for the AYN Thor (dual-screen Android handheld). Everything is gated so desktop builds are unaffected.

What's in it

GLES 3.2 backend for the compute renderer (NDS_GLES, Android-only in CMake)

  • ES-profile context selection in ComputeHost; version check replaces the glad load (GLES entry points come from libGLESv3 directly)
  • android_gl_compat.h: platform GLES headers plus shims for the desktop-only calls: glMapBuffer via glMapBufferRange, glGetTexImage via a read FBO + glReadPixels, glBindFragDataLocation no-op, GL_BGRA_INTEGER mapping with a texture swizzle on the 2D fallback texture to keep channel order correct, APIENTRYP spelling
  • Shader version headers emitted as #version 320 es with explicit precision qualifiers under NDS_GLES (compute, present, and texture-upscale shaders)

GLSL int/uint strictness fixes in the compute shaders (not gated; pure correctness)

  • GLES rejects the implicit int<->uint conversions desktop GLSL allows. All 33 compute shaders now compile on a strict driver: u-suffixed literals, explicit uint()/int() casts, matching return types. Verified on Adreno 740; desktop GL accepts all of it unchanged.

Android platform wiring (all __ANDROID__/ANDROID-gated)

  • SDL2-subproject link path in the runner CMake (the SDLActivity libmain.so model), SDL_main entry, stdio mirrored to logcat
  • Second physical display presentation: the DS bottom screen renders to an Android Presentation surface with touch mapped to the stylus (android_second_screen.*); top screen fills the main display in both the SDL and direct-GL presenters
  • Optional stub for the retail BIOS banks so a FreeBIOS-only build configures without dumps

Tested

AYN Thor (Snapdragon QCS8550 / Adreno 740, Android 13), MPH AMHE-0 banks: boots, plays, saves; compute renderer active with internal resolution up to 4x and xBR texture upscaling.

Known issue I'm still chasing

After merging current main, on-device I see black frames during the opening FMV and a slightly softer final image than my pre-merge build on the direct-GL presenter path. May be related to the presenter refactor noted in the v0.6.0 notes; I can file a separate issue with logs.

Happy to split, squash, or rework any of this however you prefer.

aabrole and others added 12 commits August 26, 2026 14:29
Runner ported to Android arm64 as libmain.so (SDL). Working on the Thor:
- FreeBIOS/no-dump boot, MPH AMHE0 title banks
- Dual physical screens: top fills main display, bottom on Screen-2
- Bottom-screen touch -> DS stylus; right-stick direct aim
- Fixes: dispatch-cache stack overflow (-O0 bionic), SDL_main linkage,
  stdio->logcat, ARGB->RGBA second-screen blit, single-window layout

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- android_gl_compat.h: GLES 3.2 header + shims for glMapBuffer, glGetTexImage
  (FBO+glReadPixels), glBindFragDataLocation (no-op), GL_BGRA_INTEGER
- CMake: Android compute build uses GLES headers + libGLESv3/EGL, drops glad
- ComputeHost: request GLES 3.2 ES context; skip glad loader on Android
- Runtime: compute renderer is now selected (preferred) on the Thor

Remaining: single-window GL surface for the compute context (Android blocks a
second window), and GLSL translation (430 core -> 320 es + subgroup rewrite).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- frontend: enable gl_top (direct-GL compute) on Android single window;
  bottom screen routed to second display in the compute present path
- GLES 3.2 context now initializes on the Thor's Adreno 740 (single-window
  blocker resolved)
- shaders: #version 320 es + precision qualifiers; startTable uint literals
- remaining: pervasive int/uint strictness in the shared Common shader math

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
int/uint strictness fixes in Common math (Div/Div64/umulExtended), span
setup, BinCombined, and const buffer-offset initializers. Shaders 1-3
(InterpSpans, *, BinCombined) now compile; numbered on-device shader dump
added to OpenGLSupport for fast line mapping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
findLSB/findMSB->uint sweep; blend/bin int-macro casts. App still runs via
software fallback throughout (compute init cleanly falls back).
All 33 compute shaders + present shaders ported to GLES 3.2 (int/uint
strictness throughout: Div/blend/rasterise/binning/finalpass/AA + present
shader version swap). Renderer now initializes as compute (no software
fallback) and renders on-device. HUGE: the HD renderer path is live.
3x internal resolution (1344x576 3D) + 2x xBR texture upscaling both run on
the Adreno 740 via GLES compute. TextureUpscale present shader version swap.
The 2D framebuffer is ARGB8888 (BGRA byte order), uploaded as GL_RGBA_INTEGER
on GLES (no BGRA_INTEGER), which transposed red/blue. Swizzle the fallback
texture (SWIZZLE_R=BLUE, SWIZZLE_B=RED) so 2D colors read correctly.
373 upstream commits: tier-2 live overlays, SDL3 default frontend (SDL2 kept
as our Android backend), expanded native banks, upstream's own element-wise
dispatch-cache clear (supersedes our Android stack fix). Android/GLES/
dual-screen patches re-folded into the new NDS_SDL_BACKEND structure.
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