Repository navigation
vk: a mesh fallback program whose compute pipeline failed is not compiled again - #1317
Merged
hckrman101 merged 1 commit intoNov 9, 2026
Conversation
…iled again fallback_compute_pipelines made the task and mesh stages' compute pipelines on a program's first fallback draw and kept them. One that failed kept nothing, so every later draw of the program compiled it again: with a driver that faults on it, one more fault caught by guarded_compute each draw. That was 12,160 faults for one program in a Kokiri Forest run on RADV, the frame down to 2-3 fps (NotRexed#1001). On a GTX 1070 (NVIDIA 580.178, Linux) the replay stopped presenting after the first fault. The failure is now kept by the program's key and variant, and its draws are left out without another try, as the first failure already left them out. tests/test_mesh_fallback_failed_once.py checks it.
This was referenced Nov 9, 2026
Closed
Closed
Closed
Closed
Closed
Closed
Closed
3 tasks done
rakefire-impala
added a commit
to rakefire-impala/Hookshot-w-Mesh-Shader-Fallback
that referenced
this pull request
Nov 10, 2026
…ompile fallback_compute_pipelines made a fallback program's compute pipelines in its first draw, under one lock. AMD's compiler took up to 12 s on one: every recording thread stopped behind it and the game froze in the first room with foliage, then the foliage and the door drew white (RX 5500M, RDNA1, no VK_EXT_mesh_shader). - fallback_pipelines_ready: the draw builds them on a worker, as dispatch() builds a compute program's pipeline (compute_state 0/1/2, which only compute programs used; RX_VK_COMPUTE_SERIAL as there). The draw that starts the build waits up to 50 ms for it, which covers NVIDIA's compiles; a draw while it still compiles is left out, as a dispatch is. - fallback_compute_pipelines is the build. Its lock now covers NotRexed#1317's failure set and the program's pipelines, not the compiles, so several programs compile at once on the workers and in the precompile. A failure is still remembered by key and variant before the return, and not tried again (tests/test_mesh_fallback_failed_once.py, unchanged, passes). - precompile_run builds every fallback program's pipelines with the compute programs', before play. program_cache_load_some takes a new fallbacks flag, which only the precompile sets, and then loads every program translated for the fallback (kind 4), not only those the notes name, whatever the compute list (NotRexed#1417) says: right after an update is when they are cold. Only a GPU without mesh shaders has such programs. The first start after a translator change compiles them (minutes on AMD; the precompile's stall rule lets the game start and they finish behind it); later starts take them from the driver's cache. tests/test_mesh_fallback.py checks the worker, the draw, the lock's scope, the precompile and the program cache's load. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rakefire-impala
added a commit
to rakefire-impala/Hookshot-w-Mesh-Shader-Fallback
that referenced
this pull request
Nov 10, 2026
…ompile fallback_compute_pipelines made a fallback program's compute pipelines in its first draw, under one lock. AMD's compiler took up to 12 s on one: every recording thread stopped behind it and the game froze in the first room with foliage, then the foliage and the door drew white (RX 5500M, RDNA1, no VK_EXT_mesh_shader). - fallback_pipelines_ready: the draw builds them on a worker, as dispatch() builds a compute program's pipeline (compute_state 0/1/2, which only compute programs used; RX_VK_COMPUTE_SERIAL as there). The draw that starts the build waits up to 50 ms for it, which covers NVIDIA's compiles; a draw while it still compiles is left out, as a dispatch is. - fallback_compute_pipelines is the build. Its lock now covers NotRexed#1317's failure set and the program's pipelines, not the compiles, so several programs compile at once on the workers and in the precompile. A failure is still remembered by key and variant before the return, and not tried again (tests/test_mesh_fallback_failed_once.py, unchanged, passes). - precompile_run builds every fallback program's pipelines with the compute programs', before play. program_cache_load_some takes a new fallbacks flag, which only the precompile sets, and then loads every program translated for the fallback (kind 4), not only those the notes name, whatever the compute list (NotRexed#1417) says: right after an update is when they are cold. Only a GPU without mesh shaders has such programs. The first start after a translator change compiles them (minutes on AMD; the precompile's stall rule lets the game start and they finish behind it); later starts take them from the driver's cache. tests/test_mesh_fallback.py checks the worker, the draw, the lock's scope, the precompile and the program cache's load.
NotRexed
pushed a commit
that referenced
this pull request
Nov 10, 2026
…ompile (#1512) fallback_compute_pipelines made a fallback program's compute pipelines in its first draw, under one lock. AMD's compiler took up to 12 s on one: every recording thread stopped behind it and the game froze in the first room with foliage, then the foliage and the door drew white (RX 5500M, RDNA1, no VK_EXT_mesh_shader). - fallback_pipelines_ready: the draw builds them on a worker, as dispatch() builds a compute program's pipeline (compute_state 0/1/2, which only compute programs used; RX_VK_COMPUTE_SERIAL as there). The draw that starts the build waits up to 50 ms for it, which covers NVIDIA's compiles; a draw while it still compiles is left out, as a dispatch is. - fallback_compute_pipelines is the build. Its lock now covers #1317's failure set and the program's pipelines, not the compiles, so several programs compile at once on the workers and in the precompile. A failure is still remembered by key and variant before the return, and not tried again (tests/test_mesh_fallback_failed_once.py, unchanged, passes). - precompile_run builds every fallback program's pipelines with the compute programs', before play. program_cache_load_some takes a new fallbacks flag, which only the precompile sets, and then loads every program translated for the fallback (kind 4), not only those the notes name, whatever the compute list (#1417) says: right after an update is when they are cold. Only a GPU without mesh shaders has such programs. The first start after a translator change compiles them (minutes on AMD; the precompile's stall rule lets the game start and they finish behind it); later starts take them from the driver's cache. tests/test_mesh_fallback.py checks the worker, the draw, the lock's scope, the precompile and the program cache's load.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fallback_compute_pipelines(gpu/vk/vk_draw.cpp) builds the task and mesh compute pipelines on a program's first fallback draw. When one fails, nothing is kept, so every later draw of that program compiles it again. With a driver that faults on the module, each try is one more fault caught byguarded_compute:a5da9f84b72d1471in one Kokiri Forest run, and 2–3 fps, because the replay retried that pipeline on every draw.With this change, the failure is remembered by the program's key and variant, and its draws are left out without another try. That is what the first failure already did for that draw. A program the driver can't compile then costs one missing effect instead of the frame rate. The fix behind those faults is the separate #792 port. This change only stops the next bad module from costing the frame rate again.
std::setof (key, variant) under the function's existing mutex, soProgramkeeps its layout and the program cache's stamp doesn't change.tests/test_mesh_fallback_failed_once.pychecks that the record is kept, checked under the lock beforeguarded_compute, and written before the return. I validated the test by mutation: it fails on main, without the check and without the insert.hookshot_vk.sobuilds on Linux with it, andpython -I -B tests/run_all.pypasses, exceptnx2/test_nup_read_name.py(zstandardis missing on my machine; it fails the same way on main). It has not been run in game: with #792's fixes, the GTX 1070 no longer reaches this path.