Skip to content

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

Closed
ZurielAtr wants to merge 1 commit into
NotRexed:mainfrom
ZurielAtr:fix/compute-table-precompile
Closed

ZurielAtr wants to merge 1 commit into
NotRexed:mainfrom
ZurielAtr:fix/compute-table-precompile

Conversation

@ZurielAtr

Copy link
Copy Markdown
Contributor

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

…able

The shader precompile translates with no program bound, so vk_bank.cpp's cs_layout had no control section to read and
every compute program it prepared kept Maxwell's storage buffer table at 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 gave the
game that translation from then on. OoT's foliage culling then left some of its draw lists empty: plants near Link had
no leaves (issue 590). With RX_VK_NO_PROGRAM_CACHE=1, where every program is translated in play with the program bound,
they had them.

parse_code now reads the table from the compute stage's own control section (+0xa9, +0xb1, +0xb2, +0xb3, +0xb6, as
cs_layout does; the sum matches the bank size at +0xba for all 3808), and the compute translation takes it when the state
has no program bound. RX_VK_CS_TABLE_SEED=0: as before.

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

Nitnek commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

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:

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

MMajor87 commented Nov 9, 2026

Copy link
Copy Markdown

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 Vegetation textures not loading correctly and foliage flickering #811 / Visual regressions after latest update: foliage LOD pop-out, crushed black shadows, untextured green geometry #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

NotRexed commented Nov 9, 2026

Copy link
Copy Markdown
Owner

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

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.

4 participants