Skip to content

PR #89 split 2/4: honour render flags on non-widescreen ports - #144

Merged
mstan merged 1 commit into
mainfrom
split89/render-flags
Oct 3, 2026
Merged

mstan merged 1 commit into
mainfrom
split89/render-flags

Conversation

@mstan

@mstan mstan commented Oct 3, 2026

Copy link
Copy Markdown
Member

Part 2 of 4 of the split of #89 (@TechnicallyComputers): stop discarding the render flags on ports that are not natively widescreen. The commit is the contributor's bf7ceca, cherry-picked with -x, unchanged.

PreparePpuFrame passed g_ppu_render_flags to the PPU only when g_game->native_widescreen was set. The shared default config ships NewRenderer = 1 and NoSpriteLimits = 1. So every port on the shared desktop host has been running the legacy rasteriser with sprite limits on, whatever its config said. With this change both keys are honoured.

Which titles this affects

Only ports that link the shared runner/src/desktop/host_main.c. Of the 16 local ports tried, those are MMX, MMX2, MMX3, Super Metroid, Yoshi's Island and BS F-Zero 2. SMW, Zelda, StarFox, SMK, SMRPG, F-Zero, Illusion of Gaia, DKC2 and Gundam W have their own host. Their exe is byte-identical between main and this branch, and SMW's src/main.c builds its own render flags.

Evidence

Every title was built against 097a355 + this commit, with gen regenerated by the main recompiler, mingw gcc Release, trace off. Each ran headless twice:

  • attract: no input, 6000 frames.
  • play: menus, then walk/jump/fire, 6021 frames.

Each run used DisableFrameDelay=1, so there is one present per frame. Present CRCs came from SNESRECOMP_PRESENT_LOG, per-frame WRAM CRCs from --framedump, and the final dump covered WRAM, VRAM, CGRAM and OAM.

Configs compared:

  • R0 = NewRenderer=0, NoSpriteLimits=0. This is main's behaviour.
  • R1 = NewRenderer=1, NoSpriteLimits=0.
  • R2 = NewRenderer=1, NoSpriteLimits=1. This is what the shipped configs now get.
title frames main vs R0 R0 vs R1 (renderer) R0 vs R2 (shipped config) WRAM / final state shipped NR/NSL
MMX 6000 + 6021 0 0 0 identical 1/1
MMX2 6000 + 6021 0 0 0 identical 1/1
MMX3 6000 + 6021 0 0 0 identical 1/1
Super Metroid (feat/authority-correctness ff02072) 6000 + 6021 0 0 0 identical 1/1
Yoshi's Island 6000 + 6021 0 0 0 identical incl. SRAM 1/1
BS F-Zero 2 6000 + 6021 0 0 0 identical none shipped

Every presented frame is byte-identical. The new renderer was really active: R1/R2 ran 1.3-1.9x faster than R0.

Caveat, sprite limits: these workloads barely exercise them. OAM sampled every 60 frames peaks at 21 sprites / 31 slivers per line for the MMX family and SM. Yoshi's Island exceeds 34 slivers on one sampled frame (play 4689, lines 135-136) and is still identical, but the cause was not traced. In a scene that really overflows a line, a shipped config with NoSpriteLimits = 1 will now show the sprites hardware would drop. That is the setting the configs ask for, and it is not something this evidence measured.

Evidence and tooling are in F:/Projects/snesrecomp/_wt-pr89-builds/ (evidence/<game>/<workload>/summary.json).

🤖 Generated with Claude Code

`uint32 flags = g_game->native_widescreen ? g_ppu_render_flags : 0;`

Neither render flag is widescreen-specific. kPpuRenderFlags_NewRenderer
selects the span renderer over the per-pixel reference one, and
kPpuRenderFlags_NoSpriteLimits lifts the per-line sprite cap; widescreen is
carried by PpuSetExtraSpace and the ws* fields, not by these bits. Gating the
whole word on native_widescreen therefore discarded BOTH settings on every
port that is not natively widescreen: config `NewRenderer`, the ToggleRenderer
hotkey and `no_sprite_limits` all resolved to a value the PPU never saw, and
those ports always ran the reference rasteriser.

Measured on Super Metroid, which is affected. perf on a live session put
ppu_resolve_pixel at 35.2% and ppu_draw_whole_line_legacy at 6.4% -- 41.6% of
all CPU in the reference path. Over an identical 900-frame headless run,
task-clock falls from 3448.90 ms to 2653.53 ms, -23%, and both symbols vanish
from the profile (replaced by ppu_runLine at 9.0%). Per-line instrumentation
confirms the cause directly: before the change all 224 lines reported
renderer=legacy.

Fidelity: 103 of 103 presented frames byte-identical between the two
renderers, dumped from the same script; the only differing file was the timing
CSV. Note that wall time is identical in both runs because a headless run
paces to the simulation clock -- it sleeps rather than saturating, so only CPU
time shows the difference.

One title's fidelity evidence is not every title's. Ports that have been on
the reference rasteriser will switch renderer with this change and each wants
its own frame comparison.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit bf7ceca)
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.

2 participants