Skip to content

Specialize stable Metal branches with native Shader ownership - #337

Draft
Roxas2712 wants to merge 6 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/metal-shader-branches
Draft

Roxas2712 wants to merge 6 commits into
UNDERdecoded:mainfrom
Roxas2712:codex/metal-shader-branches

Conversation

@Roxas2712

@Roxas2712 Roxas2712 commented Oct 27, 2026 •

Copy link
Copy Markdown

Large world shaders on Apple-silicon Metal keep costly material/light branches dynamic even when their scalar controls stay fixed. Add bounded specialization of admitted float zero/one and boolean if reads, while retaining the original real Shader userdata, declarations, arithmetic, successful sends, errors and return values. Shader caches and mods continue to use their original objects. Render resolution, artwork and post-processing stay unchanged.

Immutable bounded uniform histories preserve partial arrays and matrix layout; eager variant updates preserve native batch ordering and texture ownership. Private C leases and actual native graphics-stack depth protect release/GC and raw push/pop. Unsupported Data/buffers, source syntax, resource lifetimes, later method owners, cache limits and compiler failures use the original program. Other backends and smaller shaders keep their existing entry points. Limits are 16 sources / 2 MiB of source and 16 variants per source / 64 total; POKEPORT_SHADER_BRANCHES=0 restores the original path.

Validation:

  • Independent upstream-base implementation (8d5b4387): 38 source-planner and 40 platform/passthrough policy assertions pass. Its actual M3/Metal ROM-free fixture passes 73 checks, including real Shader identity, prior-owner multiple/nil returns, partial arrays, matrix layout, stage-only samplers, mutable color inputs, released textures, hidden native stack frames, explicit Shader release/GC, Data fallback, source caps, a later method owner and a deliberate wrong-branch pixel counterexample.
  • The composed fork independently passes the same 73 actual GPU checks. Re-entering its canvas compatibility adapter deliberately fails the spatial pixel comparison; the native constructor seam offered in Preserve LOVE 11 shader coordinates without inverting embedded HUDs #193 prevents that second projection conversion. An older already-installed adapter without that seam leaves optimization disabled. Standalone upstream operation does not require the adapter.
  • Current composed source 4344eb05 on main 0191734c / frozen a5c7462ef0, unchanged Origami 1.0.9, High / 1024×768 / active FXAA: Third mean 21.29 → 11.43 ms and First 20.07 → 11.85 ms; optimized p95 12.64 / 12.89 ms. All three complete scene captures are pixel-exact excluding only the FPS HUD. This follow-up calls the real PlatformHooks.update chain once per deterministic step, with real movement and matching scene clocks. The adapter is enabled by its production default, with no QA Shader override. Source hashes, scope and preserved failed integration are documented in docs/metal-shader-branches.md.

Draft qualification limits: the console was locked, so these are internal render observations rather than OS-window or interactive 60-FPS acceptance. Outdoor, full-game and other-hardware performance remain open. Cold compilation is synchronous: an initial control accumulated 7.21 seconds across twelve first-used variants and this full-frame repeat 1.92 seconds, both outside steady samples. First-use hitches remain; no cache-cause claim is made. The existing overworld-battle Card fails in both baseline and adapter, so complete battle support is outside this result. QA keeps 20 GiB free and uses disposable identities; player saves, private runtime code, ROMs and mod assets are not included.

Contributions by Roxas2712 — https://github.com/Roxas2712. LICENSE-ROXAS2712.md retains Roxas2712's rights and grants Cedric / UNDERdecoded the specific incorporation permission with applicable credit requirements. Existing third-party notices and rights remain intact.

Follow-up: Large world shader planning repeatedly scanned complete programs for every uniform, and rewriting copied the program for every condition. Index tokens and join changed spans once, keeping the existing conservative shadow, macro, member, qualifier and literal guards. This removes a measured CPU contributor to the multi-second first-use stalls without changing quality, resolution or generated shader output.

On the two actual 98,913/96,648-byte world shader inputs, seven measured CPU repetitions after two warm-ups give median planning 418.659 → 5.157 ms and 402.507 → 4.702 ms. Rewriting drops 7.104 → 0.193 ms and 6.267 → 0.185 ms. Plans and all-zero/all-one/mixed rewrites are equal to the exact predecessor. The isolated planner speedup is not a frame-rate multiplier. Private shader text is not published.

The follow-up planner passes 48 assertions and retains the 40 platform/passthrough policy checks; the composed current-main regression passes 250 frozen groups. See docs/qa/native-foundation/shader-planning.md for measured costs and the remaining native first-use stalls.

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