Compute programs prepared before the game find their storage buffer table #761

Closed
ZurielAtr wants to merge 1 commit from fix/compute-table-precompile into main
ZurielAtr commented 2026-11-08 20:19:19 +00:00 (Migrated from github.com)

What

The shader precompile (seed_program) translates every compute program with a blank NvnState. NVN2 compute keeps its
storage buffer table in c0 after the push area and the uniform buffer table, and vk_bank.cpp cs_layout finds it from
the bound program's control section. With nothing bound it says nothing, so translate_into fell back to Maxwell's
0x310, where NVN2's c0 holds nothing. 3756 of the game's 3808 compute programs have storage buffers.

Compute programs have no variants, so the program cache handed the game that translation from then on. OoT's foliage
culling then left some of its draw lists empty: plants near Link lost their leaves (the bushes in Hyrule Field, the plants
by the rocks), while the far impostors were fine.

Fix

parse_code reads the table from the compute stage's own control section, the same bytes cs_layout reads
(+0xa9 push words, +0xb1 uniform buffers, +0xb2 storage buffers, +0xb3 textures, +0xb6 images). For all 3808
compute programs in the game the sum matches the bank size the control section stores at +0xba. The compute translation
uses it only when the state has no program bound, i.e. for the precompile. RX_VK_CS_TABLE_SEED=0 turns it off.

Changing vk_shader.cpp changes the shader stamp, so the caches are prepared again on the first start.

Testing

  • RX 7700S (laptop), Adrenalin 26.10.1, Windows 11, Hyrule Field by the rocks with the lilac plants.
    • Before: the green part of the plants vanished as Link got close (the flowers stayed). The same with
      RX_VK_NO_PROGRAM_CACHE=1 was right, which is what pointed at the prepared translations. Retranslating the seven
      foliage mesh programs in play changed nothing (their prepared and in-play IR are identical).
    • After (on v2.0.2): the plants keep their leaves up close.
    • On v2.0.3 as released, the near plants stay (the pointer fixes) but the bushes now vanish at a distance; v2.0.3 with
      this change draws them both near and far.
  • tests/test_compute_table_precompile.py (game-free, wired into source-regressions.yml): parse_code and
    cs_layout read the same control bytes with the same arithmetic over 2000 random control sections, and the translation
    takes the program's own table only when no program is bound, before the translator is told. It fails if the
    !s.prog.nstage condition is dropped.

Addresses #590.

🤖 Generated with Claude Code

## What The shader precompile (`seed_program`) translates every compute program with a blank `NvnState`. NVN2 compute keeps its storage buffer table in c0 after the push area and the uniform buffer table, and `vk_bank.cpp` `cs_layout` finds it from the *bound* program's control section. With nothing bound it says nothing, so `translate_into` fell back to Maxwell's `0x310`, where NVN2's c0 holds nothing. 3756 of the game's 3808 compute programs have storage buffers. Compute programs have no variants, so the program cache handed the game that translation from then on. OoT's foliage culling then left some of its draw lists empty: plants near Link lost their leaves (the bushes in Hyrule Field, the plants by the rocks), while the far impostors were fine. ## Fix `parse_code` reads the table from the compute stage's own control section, the same bytes `cs_layout` reads (`+0xa9` push words, `+0xb1` uniform buffers, `+0xb2` storage buffers, `+0xb3` textures, `+0xb6` images). For all 3808 compute programs in the game the sum matches the bank size the control section stores at `+0xba`. The compute translation uses it only when the state has no program bound, i.e. for the precompile. `RX_VK_CS_TABLE_SEED=0` turns it off. Changing `vk_shader.cpp` changes the shader stamp, so the caches are prepared again on the first start. ## Testing - RX 7700S (laptop), Adrenalin 26.10.1, Windows 11, Hyrule Field by the rocks with the lilac plants. - Before: the green part of the plants vanished as Link got close (the flowers stayed). The same with `RX_VK_NO_PROGRAM_CACHE=1` was right, which is what pointed at the prepared translations. Retranslating the seven foliage mesh programs in play changed nothing (their prepared and in-play IR are identical). - After (on v2.0.2): the plants keep their leaves up close. - On v2.0.3 as released, the near plants stay (the pointer fixes) but the bushes now vanish at a distance; v2.0.3 with this change draws them both near and far. - `tests/test_compute_table_precompile.py` (game-free, wired into `source-regressions.yml`): `parse_code` and `cs_layout` read the same control bytes with the same arithmetic over 2000 random control sections, and the translation takes the program's own table only when no program is bound, before the translator is told. It fails if the `!s.prog.nstage` condition is dropped. Addresses #590. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Nitnek commented 2026-11-08 21:51:35 +00:00 (Migrated from github.com)

Tested this on an RTX 3070 8 GB (Windows 11, driver 0x98960000 as the log prints it, mesh shaders yes). I built from the command line, cherry-picked onto main at 58af2c0 (v2.0.4), and played by hand from a save at the Kakariko entrance into Hyrule Field. Each build prepared its shaders again (the stamp changes), and I moved the caches aside before switching EDEN_NX2_GM_LEGACY, so every translation matches its row.

build EDEN_NX2_GM_LEGACY distant leaves / grass floating Death Mountain trees white grass blades mid-distance in the field device lost
b179914 (port on by default) – missing beyond ~10 m gone (not drawn) no
b179914 with only afbb2d5 reverted – present back yes no
v2.0.4 + this PR default (1) present back yes no
v2.0.4 + this PR 0 (port on) – – – yes, while loading the save, 2 of 2 starts (submit … failed (-4), device lost: 0 checkpoints)

So on this card, with the port off:

  • the distant foliage is back with or without this PR;
  • the white grass, which looks like #763's "untextured" grass, is there in every build where the far grass is drawn.

With the port on, b179914 ran fine but had no distant foliage. v2.0.4 + this PR lost the device at the load every time, black screen with the audio still going. I couldn't check whether the port plus this PR draws the distant foliage and the mountain together. The logs from the two lost starts are available if useful.

Tested this on an RTX 3070 8 GB (Windows 11, driver `0x98960000` as the log prints it, mesh shaders yes). I built from the command line, cherry-picked onto `main` at `58af2c0` (v2.0.4), and played by hand from a save at the Kakariko entrance into Hyrule Field. Each build prepared its shaders again (the stamp changes), and I moved the caches aside before switching `EDEN_NX2_GM_LEGACY`, so every translation matches its row. | build | `EDEN_NX2_GM_LEGACY` | distant leaves / grass | floating Death Mountain trees | white grass blades mid-distance in the field | device lost | |---|---|---|---|---|---| | `b179914` (port on by default) | – | **missing beyond ~10 m** | gone | (not drawn) | no | | `b179914` with only `afbb2d5` reverted | – | present | back | yes | no | | v2.0.4 + this PR | default (1) | present | back | yes | no | | v2.0.4 + this PR | **0** (port on) | – | – | – | **yes, while loading the save, 2 of 2 starts** (`submit … failed (-4)`, `device lost: 0 checkpoints`) | So on this card, with the port off: - the distant foliage is back with or without this PR; - the white grass, which looks like #763's "untextured" grass, is there in every build where the far grass is drawn. With the port on, `b179914` ran fine but had no distant foliage. v2.0.4 + this PR lost the device at the load every time, black screen with the audio still going. I couldn't check whether the port plus this PR draws the distant foliage and the mountain together. The logs from the two lost starts are available if useful.
MMajor87 commented 2026-11-09 00:44:07 +00:00 (Migrated from github.com)

Tested on Windows, RTX 4080 16 GB, i9-14900KF, 32 GB: this fixes the near-plant textures there.

  • Merged onto the v2.0.5 tag: the only conflict was .github/workflows/source-regressions.yml (kept v2.0.5's); vk_shader.cpp merged cleanly, and the fix also covers v2.0.5's seed_compute (blank state, !s.prog.nstage).
  • Official v2.0.5 on this machine showed the #811 / #763 symptom (some plants with wrong / flat textures near Link). With this PR merged: no texture issues in play (tester's report), across several sessions since.
  • First start after the merge re-prepared everything (the shader stamp changes, as expected). The log then shows 97 failed programs, constant for the whole run (from the prepare, presumably seed_compute's trial variants); 0 compute pipelines were built in play.
  • Same busy area, before / after (not the identical scene, so rough): 49.4 -> 53.2 fps on average in the world, replay 11.7 -> 9.5 ms a frame, low-fps windows 5 -> 2. The lighter replay fits fuller culled draw lists.

v2.0.5's prepare-plus makes many more compute programs before the game, so without this fix more of them carry Maxwell's 0x310 table, which fits the plant issue looking worse after v2.0.5 in #811.

Tested on Windows, RTX 4080 16 GB, i9-14900KF, 32 GB: this fixes the near-plant textures there. - Merged onto the v2.0.5 tag: the only conflict was `.github/workflows/source-regressions.yml` (kept v2.0.5's); `vk_shader.cpp` merged cleanly, and the fix also covers v2.0.5's `seed_compute` (blank state, `!s.prog.nstage`). - Official v2.0.5 on this machine showed the #811 / #763 symptom (some plants with wrong / flat textures near Link). With this PR merged: no texture issues in play (tester's report), across several sessions since. - First start after the merge re-prepared everything (the shader stamp changes, as expected). The log then shows `97 failed` programs, constant for the whole run (from the prepare, presumably `seed_compute`'s trial variants); 0 compute pipelines were built in play. - Same busy area, before / after (not the identical scene, so rough): 49.4 -> 53.2 fps on average in the world, replay 11.7 -> 9.5 ms a frame, low-fps windows 5 -> 2. The lighter replay fits fuller culled draw lists. v2.0.5's prepare-plus makes many more compute programs before the game, so without this fix more of them carry Maxwell's `0x310` table, which fits the plant issue looking worse after v2.0.5 in #811.
NotRexed commented 2026-11-09 05:30:18 +00:00 (Migrated from github.com)

Closing to keep the queue clear — please rebase on current main and reopen; thanks!

Closing to keep the queue clear — please rebase on current main and reopen; thanks!
Commenting is not possible because the repository is archived.
No description provided.