Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1e8fddb
Specialize stable Metal branches with native Shader ownership
Roxas2712 Oct 27, 2026
5e6a2e2
Document full native-frame shader qualification and remaining limits
Roxas2712 Oct 27, 2026
c9d7072
Plan and rewrite large branch shaders without repeated program copies
Roxas2712 Oct 28, 2026
b4f1851
Index shader identifier guards in one source pass
Roxas2712 Oct 28, 2026
8836ff1
Document actual shader planning costs and remaining native frame stalls
Roxas2712 Oct 28, 2026
b1ad666
Record final native GPU contracts for linear shader planning
Roxas2712 Oct 28, 2026
5587a16
Compile target-specific Metal cutout variants with native method owne…
Roxas2712 Oct 28, 2026
192b495
Verify live shader programs across lazy native depth ownership
Roxas2712 Oct 28, 2026
089d385
Run native depth and sampler source contracts in CI
Roxas2712 Oct 28, 2026
39a1b4e
Attest native shader predecessors without masking foreign value owners
Roxas2712 Oct 28, 2026
ef85969
Check foreign uniform transforms against independent native pixels
Roxas2712 Oct 28, 2026
92d38e0
Document offered native target-specific shader contracts
Roxas2712 Oct 28, 2026
6824106
Record final offered-source Metal contract
Roxas2712 Oct 28, 2026
fcaecd1
Keep macro-local uniform shadows on their native shader path
Roxas2712 Oct 28, 2026
57fa2ef
Document offered macro-shadow pixel protection
Roxas2712 Oct 28, 2026
f6e87f3
Record actual offered-source native macro pixels
Roxas2712 Oct 28, 2026
7b140d5
Keep observed intermediate shader floats dynamic at later endpoints
Roxas2712 Oct 28, 2026
6942bef
Document offered native shader transition cache
Roxas2712 Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/native-depth-variants.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Native depth shader variants
on:
pull_request:
paths:
- 'main.lua'
- 'src/render/AlphaDepthCompat.lua'
- 'src/render/ShaderSpecialization.lua'
- 'src/render/ShaderSamplerGuard.lua'
- 'tests/engine/alpha_depth_compat.lua'
- 'tests/engine/shader_sampler_guard.lua'
- 'tests/engine/shader_specialization_policy.lua'
- 'tests/native_shader/**'
- '.github/workflows/native-depth-variants.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
contracts:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v7
- run: sudo apt-get update && sudo apt-get install -y luajit
- name: Native source guards and target ownership
run: |
luajit tests/engine/alpha_depth_compat.lua
luajit tests/engine/shader_sampler_guard.lua
luajit tests/engine/shader_branches.lua
luajit tests/engine/shader_specialization_policy.lua
88 changes: 88 additions & 0 deletions LICENSE-ROXAS2712.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Roxas2712 — Fork Contributions

Version 1.0 · Effective 25 October 2026

Copyright © 2026 Roxas2712, to the extent of rights held.
All rights reserved except as expressly granted below or already granted.

## 1. Scope and ownership

This notice applies only to original contributions made by Roxas2712
(GitHub: Roxas2712) to `Roxas2712/Gen2Recomped`, including original additions
within modified files, insofar as he owns the relevant rights. Git history,
pull-request diffs and source provenance identify contributions; a commit
author or a whole-file change alone does not establish ownership of every
part of that file.

It does not claim ownership of Cedric's work, Gen1Recomp / BOIS CLUB GAMES
work, other contributors' work, third-party dependencies, or ROM-derived
content. Their applicable licences and notices remain in force. It does not
grant permission to distribute the complete combined fork where another
rights holder's permission is required.

## 2. General permission and reserved rights

For contributions covered by this notice and not already licensed more
broadly, you may read and study the published source and make private,
non-commercial modifications and builds for your own use. This grants no
general permission to redistribute, sublicense, sell, or offer those
contributions as a hosted service. Other uses require Roxas2712's
written permission, except for the specific permission below and rights
available independently under applicable law.

Keep the relevant copyright, licence and attribution notices. Do not
represent Roxas2712's contributions as exclusively authored by someone
else. Public source availability alone does not put them in the public
domain or grant an open-source licence.

## 3. Specific permission for Cedric / UNDERdecoded

Roxas2712 expressly grants Cedric (Ced; GitHub: UNDERdecoded /
UNDERdecodedHD) a non-exclusive, worldwide, perpetual, royalty-free
permission to use, reproduce, integrate, modify and distribute the covered
contributions that Roxas2712 submits or expressly offers through pull
requests to `UNDERdecoded/Gen2Recomped`, for Cedric's Gen2Recomped /
RetroRecompiled project. This includes its renamed continuation maintained
by Cedric, its official builds, and its commercial operation.

Cedric may license the incorporated contributions to recipients as part of
that project, subject to preserving this permission's applicable credit and
notice requirements. This permission is not a copyright assignment, is not
exclusive, and does not cover unpublished work, separate repositories,
ModCompass service operation, credentials, or content not offered in those
pull requests. Roxas2712 retains his own rights to his contributions.

For uses relying on this permission:

- retain the relevant source copyright and licence notices;
- give visible credit in the project's README or equivalent public project
page, and in the application's existing About / Credits view, if present;
- use at least the following credit, or a substantially equivalent one:

> Contributions by Roxas2712 —
> https://github.com/Roxas2712

A maintained consolidated contributor credit is sufficient; a separate
credit on every screen or for every change is not required. Adapted
contributions must not be attributed exclusively to another author. Other
contributors' credits must also remain intact.

## 4. Earlier licences and permissions remain effective

This notice does not revoke, narrow, or retrospectively add conditions to
any permission already validly granted, including MIT / GPL grants,
separate agreements, or permissions arising from previously submitted
pull requests. Where an earlier grant permits a use independently of this
notice, its existing terms govern that use. For such earlier uses, the
visible credit above is requested to the extent it is not already required.

For subsequent contributions, this is the default statement of Roxas2712's own reserved rights and the specific PR permission, subject to any
applicable existing licence obligations or separately agreed terms. It
does not change another rights holder's licence or guarantee compatibility
of a particular combination of code.

## 5. No warranty

To the extent permitted by applicable law, these contributions are provided
as is, without warranty. No support obligation, endorsement, or rights to
third-party code, game assets, names, or trademarks are granted.
105 changes: 105 additions & 0 deletions docs/metal-shader-branches.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Bounded Metal shader branch specialization

Large world programs can keep expensive lighting/material branches dynamic even
when their scalar controls stay at zero or one. On Apple-silicon macOS with
LÖVE 12/Metal, the native compiler adapter specializes eligible `if` reads of
positive float zero/one and booleans. It preserves declarations, arithmetic,
source artwork, render resolution and post-processing. It uses no mod names or
private shader snippets. Other backends, smaller programs and unsupported
source/value shapes keep their original programs.

The caller retains the real original Shader userdata and interface. Every
successful `send`/`sendColor` updates that C shader first; original errors,
return arity and nil values remain intact. Bounded immutable snapshots preserve
partial uniform-array tails and per-send matrix layout. Eager variant writes
preserve batch ordering and release replaced C texture references. Missing or
released replay resources, mutable Data, buffers and unknown values fall back
to the original. A later foreign Shader-method owner also disables optimization.

An unnamed Channel holds the original C shader without keeping its Lua userdata
alive. Retirement queries the real native graphics-stack depth, including raw C
push/pop calls. Disabled/orphan records retire only at an empty-stack boundary;
hidden native stack frames keep their mappings and C leases. Public `getShader`
returns the original live interface, including native reconstruction after
explicit release. No public reference-count API is assumed.

Sampler declarations remain visible to the Metal stage linker behind a private
zero-valued guard. Vertex-only declarations stay in their stage; unsupported
syntax or compilation failure retains the original program. The optional canvas
compatibility adapter provides its preceding constructor as `compileNative`:
derived programs must not have their already admitted clip convention analyzed
again after their forwarding entry is modified. An older installed adapter
without this seam leaves specialization disabled. No producer macro is injected.

Limits: 64–256 KiB per eligible source, 16 live sources, 2 MiB combined source,
16 variants per source, 64 live variants, 256 observed uniforms and 32,768
snapshot nodes per source. Source shadowing/macros and unsupported shapes stay
conservative. `POKEPORT_SHADER_BRANCHES=0` restores the original compiler path.

## Native qualification

Frozen native source `a5c7462ef0`, committed compiler `4344eb05` on fork main
`0191734c`, unchanged private Origami 1.0.9 `ae59c77c`: baseline `562ad4a1f9`
versus default-enabled native adapter `de603b9839`. Both use actual Metal on
M3/16 GB, High, 1024×768 scene/window, active FXAA, render scale one,
supersampling off and native VSync off. No QA Shader prototype is installed.

The QA input adapter replaces only the deterministic driver's direct Game
update call in memory with the real `PlatformHooks.update(Game, 1/60)` owner.
Engine and mod files remain unchanged. The complete outer mod hook chain runs
exactly once per measured step; native renderer serial also advances once.
Each view measures 120 ordinary directional-input frames after settling and a
separate collection/recovery test. The player occupies 17 / 13 / 13 distinct
native positions in open/Third/First, and scene clocks match across both runs.
The shared hardware lease covers source setup through final cleanup.

| View | Original mean ms | Adapter mean ms | Adapter p95 ms | Adapter max ms |
| --- | ---: | ---: | ---: | ---: |
| open | 6.77 | 6.21 | 10.61 | 12.07 |
| third | 21.29 | 11.43 | 12.64 | 14.24 |
| first | 20.07 | 11.85 | 12.89 | 15.65 |

All three complete scene captures are pixel-exact, excluding only the changing
FPS HUD (`x >= 890 && y < 56`). Twelve actual variants are used, with no
compiler/replay failures, unsupported values or fallback draws. The original
failed native integration (`a67197449f`) double-adapted clip space; its failure
is preserved and corrected through the constructor seam, not an image flip.

Actual default-policy GPU fixtures `586e40dc29` (composed) and `efda7ed3c9`
(standalone upstream implementation) each pass 73 checks, including spatial projection,
real Shader identity, multiple/nil returns from a prior owner, partial arrays,
matrix layout, mutable color inputs, sampler release, raw native stack frames,
Shader release/GC, Data fallback, source caps and later foreign method ownership.
Both the deliberate wrong-branch control and the separate double-projection
negative `189f31ddff` are detected. Independent public CPU qualification
`c303516873` passes 38 source / 40 policy / 128 canvas-seam assertions. Focused native engine,
orientation, JIT, map, follower, options, pacing and Crystal VRAM checks pass in
the same frozen composition.

These are internal rendering observations while the console is locked. They
are not OS-window, interactive 60-FPS, outdoor, full-game or all-platform
acceptance. Cold compilation is synchronous. Initial control `55614c8cc0` accumulated
7.21 seconds across twelve first-used variants; the full-frame repeat records
1.92 seconds. Both are outside the steady samples; no cache-cause attribution
is claimed.
First-use hitches remain a limitation; there is no asynchronous-compilation
claim. The existing overworld-battle Card fails in both baseline and adapter
runs; this change does not qualify complete battle support. Player profiles and saves are not used. QA enforces 20 GiB free, above
the requested 8 GiB minimum.

## Repeating the API fixture

`tests/native_shader` is a ROM-free LÖVE fixture. Its engine root comes from
`SHADER_TEST_ENGINE` (default: the repository containing the fixture); a frozen
runner must set it to the exact copied source. Use a disposable QA identity,
the project's managed storage/hardware runner and Metal. Set
`QA_NATIVE_SHADER_ADAPTER=1`; `QA_SHADER_MULTIPLE_RETURNS=1` additionally exercises
an existing method owner. `QA_SHADER_WRONG_COMPILER=1` deliberately re-enters the
actual canvas adapter and must fail the spatial pixel comparison. That negative
requires the canvas adapter; the standalone compiler fixture also runs without
it. Never use a player identity for this fixture.

Contributions by Roxas2712 — https://github.com/Roxas2712.
See [the contribution terms](../LICENSE-ROXAS2712.md) for Cedric / UNDERdecoded's
specific incorporation permission and applicable credit requirements. Existing
notices remain intact.
45 changes: 45 additions & 0 deletions docs/qa/native-continuous-shader-uniforms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Reuse dynamic shader programs at interpolation endpoints

Keep a qualified scalar float dynamic after a successful native write has
actually supplied a value strictly between 0 and 1. Later endpoints reuse that
runtime branch instead of compiling another endpoint-specialized program.
Independent bool flags still specialize. Original uniforms, arithmetic, native
send returns, texture ownership, graphics stacks and release remain intact.
Integer-valued modes outside the interval keep their prior treatment.

Qualification:

- The fork and actually offered public component each pass 118 real Metal
checks on LOVE12/Apple M3. These include exact reference pixels across
0 -> .25 -> 1 -> 0, an independent bool toggle, matrix/array updates,
texture Lua release, native C stack lifetime, cutouts and macro shadows.
- The exact earlier native compiler policy in an owned control host produces
the expected additional program at the endpoint. Its pixel comparisons
pass; this counterexample concerns extra compilation, not incorrect pixels.
- The unchanged private consumer bddb51819c uses 8 observed continuous uniforms.
In its real High Third-Person/rain view, the adapter retains 14 variants
throughout 120 sampled plus 120 unprofiled warm frames. Its recorded compiler
time stays 1.808914 seconds throughout those windows. The preceding policy
grows from 15 to 21 variants and 5.527151 to 7.259581 recorded compiler seconds.
- In the matched sampled window the maximum drops from 3133.971 to 137.913 ms.
Unprofiled warm mean is 56.532 ms (~17.7 FPS), draw 49.565 ms, update 5.151 ms;
all 120 rows have distinct consecutive renderer ticks. The preceding warm
mean is 59.712 ms. There are still 5368 indexed native draws and 9 mirror
planes at 512x3456; reflection coverage remains 436255 pixels. This remains
a throughput blocker. Startup/map-change stalls outside these windows
require separate qualification; 60 FPS and OS-window acceptance remain open.
- Source 15dc92fc was used for that real consumer comparison. Current fork
source 42abe561 includes main 1658cb05 with unchanged shader files and passes
eight focused groups, including the new native RS option contracts 38/148.
The preceding main a8833b35 combination passed all 252 native CPU groups.

Receipts: root Metal 5259b88625, offered Metal 9781e462f1, old-policy
counterexample 0f517b41cc, real consumer 40b62271cc, combined-main CPU 3683346023.
Quality and private source remain unchanged; only owned QA profiles are used.
The broader dead-body and argument-admission experiments are excluded.

Contributions by Roxas2712 under LICENSE-ROXAS2712.md; existing upstream and
third-party licences and rights remain intact.

Depends on the offered compiler/depth/macro stack (#337, #388, #389). Current
upstream-main composition and complete release qualification remain open.
23 changes: 23 additions & 0 deletions docs/qa/native-depth-shader-variants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Offered native target-specific shader compiler

Depends on the offered Metal branch compiler (#337). The actual older public
component now includes the native alpha-depth adapter and explicit install
before specialization; no private rendering controllers are imported.

Projected cutouts use separate bounded colour and writable-depth variants,
compiled through the exact preceding native constructor. No duplicate late
companion is created. Public userdata, uniform values, return values, resource
lifetime and native stack owners are retained. Lazy native method interposition
is admitted only after exact predecessor attestation; foreign value owners keep
the original-program fallback. Valid late sampler declarations are retained.

The actual offered component passes focused CPU contracts 69/16/48/40 for
alpha depth, sampler declaration order, planning and platform policy. The final offered-source Metal contract passes 96 checks (receipt
ab3c28b2f2); the fork implementation's foreign-owner fixture passes 79. An intentionally weaker owned-host predicate fails the foreign-owner
ownership assertion, while preceding pixel comparisons pass. No 60 FPS, complete
mod, current upstream-main composition or release qualification is claimed.

Contributions by Roxas2712 — https://github.com/Roxas2712. Original additions
are expressly offered under LICENSE-ROXAS2712.md, including Cedric/UNDERdecoded
integration/distribution permission with visible credit. Existing upstream and
third-party licences and rights remain intact.
13 changes: 13 additions & 0 deletions docs/qa/native-foundation/shader-planning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Bounded work for large shader planning

The old branch planner searched the entire program for each uniform, and its shadow check repeatedly searched identifier suffixes. Its rewriter rebuilt the complete program for each condition. Both now index identifiers and assemble changed source spans in a single pass. Existing conservative shadow, member, macro, qualifier and literal guards remain intact. Rendering resolution, shader arithmetic, uniforms, material branches and post-processing are unchanged.

On two actual world shader inputs (98,913 and 96,648 bytes, 23/22 admitted flags, 273/266 conditions), the exact predecessor and the new planner produce equal plans and byte-identical rewrites for all-zero, all-one and mixed flag banks. Seven measured CPU repetitions after two warm-ups give median planning 418.659 to 5.157 ms and 402.507 to 4.702 ms. Rewrite medians are 7.104 to 0.193 ms and 6.267 to 0.185 ms. These are isolated CPU planning measurements, not a claimed frame-rate multiplier. No private shader text is published.

The planner fixture passes 48 checks, including exact output for a generated nested large program and unchanged shadow/macro rejection. Platform/passthrough policy checks pass 40 assertions. The first optimization composition passed 246 frozen CPU groups, and both the fork and older independent public implementation passed 73 real Metal Shader-contract checks. The final token-index pass passes the actual-program byte-equivalence comparison and both independent real Metal contract repetitions (73 checks each). The later composed current-main regression, including the door descriptor integration, passes 250 frozen CPU groups. The public implementation retains its original upstream controllers.

A separate native FireRed water-view diagnostic, with the first optimization, observed an 844-ms frame (840 ms in drawing, under 1 ms in presentation). Native compilation remains synchronous and dominated the sampled slow setup. A 120-frame warm interval without the Lua sampler averaged 18.309 ms (about 55 FPS), p95 27.346 ms, maximum 42.186 ms. It used High quality, 1024x768 and a 512x384 scene reflection target. No capture, texture readback, file write or forced collection ran in either frame window. This short fixed-camera diagnostic is not stable 60-FPS, rain, Third/First-person, interactive-window or full-game acceptance. Existing first-use driver compilation remains unresolved.

QA used owned profiles, preserved private source and player saves, and enforced 20 GiB free (above the requested 8 GiB reserve).

Contributions by Roxas2712 — https://github.com/Roxas2712. See LICENSE-ROXAS2712.md for the specific integration/distribution permission for Cedric / UNDERdecoded with visible credit. Existing upstream/third-party licences and rights remain intact.
Loading