Skip to content

Fix OpenGL stage-clear wallpaper rendering upside-down#127

Merged
JRickey merged 1 commit intomainfrom
agent/opengl-fb-capture-flip-fix
May 3, 2026
Merged

Fix OpenGL stage-clear wallpaper rendering upside-down#127
JRickey merged 1 commit intomainfrom
agent/opengl-fb-capture-flip-fix

Conversation

@JRickey
Copy link
Copy Markdown
Owner

@JRickey JRickey commented May 3, 2026

Summary

  • 1P stage-clear frozen-frame wallpaper rendered upside-down on OpenGL only — D3D11 and Metal already worked.
  • port_capture_game_framebuffer was force-flipping rows on OpenGL on the assumption that glReadPixels uses bottom-left origin. That's true of raw GL, but mGameFb is created with opengl_invertY=true (libultraship/.../interpreter.cpp:5893), so the engine pre-negates vertex Y at draw time (interpreter.cpp:2761). The OGL framebuffer's bottom row is therefore already the N64 top row, and the wrapper's "compensating" flip was inverting an already-correct buffer.
  • Confirmed via a short-lived SSB64_FB_FLIP=always\|never\|auto env-var harness from a single Debug build — only never produced an upright wallpaper. Locked in as the unconditional default.
  • D3D11 / Metal ReadFramebufferToCPU walks textures in native top-left order with no analogous flag, so they were correct without any flip and remain unchanged.

Test plan

  • OpenGL backend: 1P → any stage → fight to stage clear → wallpaper renders upright (was upside-down on main).
  • D3D11 backend: regression check — stage-clear wallpaper still upright (no behaviour change in code path).
  • Metal backend: regression check — stage-clear wallpaper still upright.

Notes

  • See docs/bugs/opengl_fb_capture_y_flip_double_invert_2026-05-03.md for full root cause + audit hook.
  • mGameFbMsaaResolved is the only LUS-managed FB built with invertY=false. Capture only reaches it on the OGL+MSAA+non-matching-viewport sub-config, which we couldn't trigger in the A/B session — if a future report describes upside-down only with MSAA on, this is the next likely place to look.

🤖 Generated with Claude Code

The capture path was force-flipping rows on OpenGL on the assumption that
glReadPixels uses bottom-left origin, but mGameFb is created with
opengl_invertY=true (interpreter.cpp:5893) so the engine pre-negates
vertex Y at draw time (interpreter.cpp:2761). The OGL framebuffer's
bottom row is therefore already the N64 top row, and the wrapper's
compensating flip was inverting an already-correct buffer. D3D11 / Metal
have no analogous flag and never needed a flip.

Confirmed via a short-lived SSB64_FB_FLIP=always|never|auto env-var
harness — only "never" produced an upright wallpaper on OpenGL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JRickey JRickey merged commit 9742fab into main May 3, 2026
@JRickey JRickey deleted the agent/opengl-fb-capture-flip-fix branch May 3, 2026 21:38
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