Skip to content

nvn: repair MGS4 rendering, launch handoff and FMV audio - #2665

Open
cosmin-cucu wants to merge 6 commits into
seedds:mainfrom
cosmin-cucu:fix/mgs4-runtime-repairs
Open

cosmin-cucu wants to merge 6 commits into
seedds:mainfrom
cosmin-cucu:fix/mgs4-runtime-repairs

Conversation

@cosmin-cucu

@cosmin-cucu cosmin-cucu commented Nov 14, 2026 •

Copy link
Copy Markdown

What and why

MGS4 could not complete the collection-to-game handoff, then lost HUD/character/particle draws, joined unrelated triangles into cyan streaks, and played FMVs without sound. This PR collects the five repairs found during that bring-up, each in its own commit, plus a test-fixture follow-up:

  • Recognize the exact VPAK archive header through the existing NVN record reader and include validated prefixed shader records embedded in main.
  • Return the host's local user once after a valid program handoff, preserving HOME launch behavior and handle validation.
  • Validate the vertex bytes a draw can fetch instead of requiring the whole advertised binding to fit. Revalidate larger cached spans and follow fully covering, ordered uploads back to an unchanged CPU source when proving index ranges. Unknown/partial/sparse or subsequently changed sources remain conservative.
  • Compact complete triangles between triangle-list restart markers into one indexed draw, preserving base vertex and instancing.
  • Reserve synchronous audio catch-up renders for renderers with effect capacity. Zero-effect FMV renderers can prime stopped voices without consuming their buffers before collective startup.

Findings are recorded in shaders, services, rendering, and audio.

The game's provisional profiles, launch configuration, English text overlay, engine FPS setting, pipeline cache and MetalFX configuration are local and are not part of this PR. No game assets are included.

Checked

  • Apple M2 Max (32 GB), macOS 27.2.1, Xcode 27.2.
  • python -m unittest discover -s dm/tools/tests -p 'test_split_*.py': 89 tests passed, including five synthetic VPAK/embedded-record tests.
  • make -C dm/host/tests GAME=0100D0B01C4F4002 account audren-work audren-layout: passed. Includes handoff/capacity/repeated-pop/invalid-handle checks, twenty rapid zero-effect updates, and SDK 4/5/6/16/21 audio layouts.
  • Python lint ratchet: 321 baseline findings, zero new findings. Documentation tests: six passed. git diff --check passed.
  • Full graphics suite built and ran with make -k -C dm/gfx/tests GAME=0100D0B01C4F4002 run. Three fixtures (t_render_counter_overlap, t_render_enable_queue, t_wait_event) initially faulted on tracked upload pages. They now install the production dirty-page fault handler, as does t_mdx_prescan; all affected targets passed when rerun. All other suite targets passed in the complete run. Final reruns: prescan six cases, counter overlap 37 checks in both modes, render enable 62 checks in both modes, event wait 106 checks. No product source changed after the full run.
  • Graphics coverage includes vertex buffers (192 checks, cache on/off), copy aliases (126 checks in both encoder modes), upload ordering (25), geometry hazards (61 in three configurations), and triangle-list restart (91 in both encoder modes). Feedback snapshots passed (336 checks) on current upstream.
  • C lint limitation: the compilation database was generated (309 sources), but clang-tidy is not installed, so C lint was not run.

Manual play on the tested pre-rebase build: MGS4 program 0100D0B01C4F4002, update v393216 / 1.4.4; collection program 0100D0B01C4F4000 successfully handed off to it. Practice scene and opening story/FMVs were exercised over repeated diagnostic runs. The player confirmed intact limbs, correct grenade/RPG explosions, disappearance of cyan streaks, and audible FMV sound. Later street gameplay had correct geometry. With separate local configuration changes, the player also confirmed normal-speed, smooth 60 fps gameplay at docked 1080p with MetalFX spatial upscaling to 1440p. Those FPS/resolution settings are not a source-code performance claim. Full progression and save/load progression were not exercised.

After rebasing onto 4b10c73ffb26, the checks above were rerun. The rebase retained upstream's new sparse-texture helpers and only reconciled a relocated forward declaration. Gameplay was not repeated on the rebased build.

Static regression against current main (4b10c73ffb26), candidate 081a0e80fa02 (before the test-only fault-handler follow-up), scripts/regress.py check --no-smoke:

Collection program Baseline shaders Candidate shaders Newly failing Changed MSL / interfaces
0100D0B01C4F4000 752/752 752/752 0 0 / 0
0100D0B01C4F4001 2873/2873 2873/2873 0 0 / 0
0100D0B01C4F4002 998/998 998/998 0 0 / 0
0100D0B01C4F4003 486/486 486/486 0 0 / 0

Only these four local collection programs were available; this is static shader validation, not four-game gameplay coverage. No smoke routes were available for the provisional profiles. Impact analysis also identifies BOTW, Pokémon Scarlet and TOTK, plus broad shared-host exposure; those games were not available for regression play. Other games using zero-effect audio renderers, iOS, database/flashback gameplay, return-to-launcher and cloud save synchronization remain unverified. Copy-source protection can introduce CPU write faults; long-session frame pacing remains unmeasured.

Docs

  • Findings are in the subsystem reference entries and dm/tools/docs_symptoms.py was run.
  • No game files, keys or extracted game data in the change or attachments.
  • No shader-chain tool changed in this PR; no chain-header update is needed.

Recognize the validated VPAK header and reuse the existing adjacent code/control reader. Scan length-prefixed records in main without accepting unrelated unprefixed bytes. Found on MGS4: the audited set contains 998 unique shaders, including movie shaders missing from the aligned scan.
Return the always-open local user once after a valid previous-program handoff, preserving HOME fallback, capacity handling and invalid-handle validation. MGS4 consumes the inherited handle directly after collection launch.
Do not reject a valid draw because its declared stream limit extends beyond the memory pool. Track safe fetch spans, revalidate cached bindings for larger spans, and follow fully covering ordered index uploads to unchanged CPU sources. Preserve conservative handling of unknown GPU writes and sparse aliases.
Metal does not restart triangle lists at the game's separator indices. Expand complete triangles between separators into one indexed draw, preserving base vertex, instancing and continuous primitive IDs. Use verified upload sources or synchronize unknown GPU-written indices before reading.
Bink primes stopped voices across several updates before starting them together. Synchronous catch-up renders released those buffers too early and left movies silent. Retain effect capacity from open and only apply the effect-initialization safeguard to renderers that can have effects.
@github-actions github-actions Bot added host The Horizon host: SVCs, services, threads, memory (dm/host) nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers tools Tools and scripts (dm/tools, scripts) docs Documentation labels Nov 14, 2026
@cosmin-cucu
cosmin-cucu force-pushed the fix/mgs4-runtime-repairs branch from 70f4606 to bdd62ce Compare November 14, 2026 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation host The Horizon host: SVCs, services, threads, memory (dm/host) nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) packing Building an IPA or a Mac app: the NSP script, extraction, the shader split, the packers tools Tools and scripts (dm/tools, scripts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants