Skip to content

Apply Internal resolution and Supersampling live from the in-game menu - #737

Merged
mstan merged 12 commits into
masterfrom
feat/live-resolution
Oct 23, 2026
Merged

mstan merged 12 commits into
masterfrom
feat/live-resolution

Conversation

@tetrisgm

Copy link
Copy Markdown
Member

What:

  • Internal resolution and supersample are live settings (PSX_VIDEO_LIVE_RESOLUTION): the new scale applies at the next frame through the dynamic-resolution step machinery (gl_renderer_set_internal_scale_live: moves the step ceiling, clamped like the boot scale, and records the step in stream order with the render thread). The dynamic-resolution controller is retargeted to the new ceiling. Only the legacy integer supersampling factor still needs a relaunch.
  • settings.toml [video] supersample is the player's pick (1.0..4.0), saved by the menu.
  • The in-game menu round-trips internal_resolution (it was never copied back, so changing it did nothing until a relaunch) and, with a launcher that has RECOMP_LAUNCHER_HAS_SUPERSAMPLE, supersample_milli.
  • Debug-tools builds: video_set drives the same path.

Why: owner: resolution and supersampling must be settable in game and take effect immediately.

Verified (R4, RTX 4080, 8K): via video_set in a race, each change applied within 0.5 s with no relaunch: 1080p 5x, 4K 9x, 4K+2x 18x, Match display 18x, 720p+1.5x 5x. host_overlay_test updated and passing; R4 ctest 22/22.

Sibling: RetroPortingToolKit/recomp-launcher#3

🤖 Generated with Claude Code

tetrisgm and others added 5 commits October 22, 2026 10:43
Changing the internal resolution in the in-game menu did nothing until a
relaunch: ovl_video_from() never copied it, and the restart bits forced
a relaunch for it anyway. Supersampling (the [video] supersample
multiplier) had no player setting at all.

- PsxHostVideoSettings gains supersample_milli; internal resolution and
  supersample are live changes (PSX_VIDEO_LIVE_RESOLUTION). Only the
  legacy integer supersampling factor still needs a relaunch.
- psx_video_apply_live resolves the new scale and calls
  gl_renderer_set_internal_scale_live(): it moves the step ceiling
  (clamped like the boot scale) and queues the step through the dynamic
  resolution machinery, recorded in stream order with the render thread.
  The dynamic-resolution controller is retargeted to the new ceiling.
- settings.toml [video] supersample is the player's pick (1.0..4.0).
- The in-game menu round-trips internal_resolution and, with a launcher
  that has RECOMP_LAUNCHER_HAS_SUPERSAMPLE, supersample_milli.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mmand

psx_video_current reported the live scale as the legacy supersampling
factor, so a second live change looked like a legacy edit and asked for
a relaunch. Report the boot value. Debug-tools builds gain video_set
(internal_resolution, supersample) to drive the live path in tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@mstan mstan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Live resolution is meaningful and the existing dynamic-scale machinery is the right starting point. The current capability/result contract is wrong for several supported cases: psx_host_video_restart_bits now always excludes internal_resolution, but psx_video_apply_live only attempts GL and gl_renderer_set_internal_scale_live returns 0 for hiw, CPU-authoritative dual rendering, missing context or unavailable resources. These paths still update/save the requested settings and report restart=0 even though the image did not change. Please distinguish requested settings from the last successfully applied settings, retain a resolution restart requirement whenever live application is unavailable/refused, and expose truthful per-backend/menu capability. Reject invalid video_set presets/factors without saving them or reporting success, and regenerate the TCP command index. A focused GL live-change check plus one refused/non-GL check is enough to establish this contract; no new opt-in is needed for the round-trip correctness repair. Tracking: beads-ek8k.

Keep the requested internal resolution / supersample (shown and saved)
apart from what the backend last applied. When the live change is
unavailable (no GL, windowed high-resolution mode, CPU-authoritative dual
rendering, no context) or refused, the session scale is left as applied and
PSX_VIDEO_RESTART_RESOLUTION stays set, in both psx_video_apply_live and
the menu's restart bits (psx_host_video_restart_bits_backend, unit-tested
for the capable and refused cases). video_set rejects invalid presets and
factors without applying or saving, and reports applied values, capability
and pending restart. TCP command index regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tetrisgm

Copy link
Copy Markdown
Member Author

Addressed in b1ce3be: requested resolution (shown and saved) is now kept apart from the last applied one. When a live change is unavailable (no GL, hiw, CPU-authoritative dual, no context) or refused, the scale stays as applied and PSX_VIDEO_RESTART_RESOLUTION stays set, both in psx_video_apply_live and in the menu's restart bits. That logic is psx_host_video_restart_bits_backend, unit-tested for the capable and refused cases. video_set rejects invalid presets and factors without applying or saving anything, and it reports the applied values, live_capable and restart_pending. The TCP command index is regenerated.

@mstan

mstan commented Oct 22, 2026

Copy link
Copy Markdown
Member

Re-reviewed b1ce3be. Backend capability, input rejection and regenerated command index address substantial feedback. The applied-state contract still acknowledges a queued request as if allocation and application have completed: gl_renderer_set_internal_scale_live queues through gl_renderer_request_internal_scale, while the later dyn_apply can refuse allocation. g_video_res_applied_* is already advanced and the failure flag cleared at that point. Please acknowledge successful backend application, retain pending/refused status through the frame boundary, and test an allocation refusal after enqueue. Restart comparison must also use the last actually applied resolution rather than only the boot settings: after a successful live A->B change, a refused B->A request currently compares equal to boot A and can report no resolution restart while the image remains at B. A focused state-transition witness for this sequence and a GL/non-GL check is enough; no full gameplay matrix is requested. This head remains held and is outside the current frozen game batch. Tracking: beads-ek8k.

tetrisgm added a commit to tetrisgm/psxrecomp that referenced this pull request Oct 22, 2026
Live resolution (RetroPortingToolKit#737) routes mh_restart_bits through main.cpp's
backend-aware video_restart_bits; the fixture extracts mh_restart_bits
alone, so it no longer compiled. Map it to the fixture's
psx_host_video_restart_bits (no live resolution here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tetrisgm and others added 5 commits October 22, 2026 16:48
Live resolution (#737) routes mh_restart_bits through main.cpp's
backend-aware video_restart_bits; the fixture extracts mh_restart_bits
alone, so it no longer compiled. Map it to the fixture's
psx_host_video_restart_bits (no live resolution here).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	docs/TCP_COMMANDS.md
#	generated/OpenBIOS.emitter.sha
@mstan

mstan commented Oct 23, 2026

Copy link
Copy Markdown
Member

Maintainer corrections pushed in 674f393 (your new 0ec7c76 menu-fixture fix is preserved). Live resolution now drains/acquires the GL owner and confirms successful allocation/application before advancing applied settings; refusal preserves the previous scale/ceiling and cannot later apply the refused request. Restart comparison uses the last confirmed resolution, so successful A->B followed by refused B->A still requests a restart even when A was the boot value. Applied resolution/supersample publication is coherent.

The actual GL fixture injects an allocation failure without exhausting VRAM, checks refusal/recovery, and preserves matching native/high-resolution/wide pixels with the render thread off/on at 1x and 3x. The focused restart-transition checks pass too. Current-master integration conflicts were resolved, and OpenBIOS was genuinely regenerated with byte-identical C before restamping. The four-title smoke batch is underway; I will reconsider merge after it completes. Tracking: beads-kgof.

@mstan mstan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maintainer fixes confirm GL allocation/application synchronously before advancing applied settings. Allocation refusal preserves scale/ceiling and cannot apply later. Restart comparison uses the last confirmed values; applied values publish coherently and reset per execution session. Real GL allocation-refusal/recovery and 1x/3x threaded/unthreaded pixel fixtures pass. Actual Tomba live native->480->native reports confirmed 1x->2x->1x with no restart pending. The author menu snapshot change is retained and its concurrent reader fixture passes.

One bounded muted OpenGL boot/progression/visual smoke passed for Tomba, Tomba 2, Ape Escape and Mega Man X6. Tomba 2 reached its title screen after the opening FMV at native aspect; its unsupported widescreen package remains disabled. Supported debug quit returned exit 0 for all four; this is not extended gameplay, normal-teardown or native-card-write qualification.

Combined integration 9ee1a8c63996cc91e4068aa27f100d407ab1ac0e includes #710/#723/#736/#737/#746; #736 remains held for residency policy. Six focused native checks and the GL fixture passed. This evidence qualifies the reviewed heads as a compatible subset, not an exact final-master-tree claim. Tracking: beads-kgof.

@mstan
mstan merged commit afc8284 into master Oct 23, 2026
1 check passed
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