Repository navigation
fix(vk): a masked clear whose pipeline the driver did not make is tried again, not cached as null (#1787) - #1880
Conversation
…ed again, not cached as null (NotRexed#1787) clear_pipeline ignored what vkCreatePipelineLayout and vkCreateShaderModule returned and cached whatever cached_graphics gave back, so one transient driver failure left that masked clear out for the rest of the run. Each step's result is now checked; a failure keeps nothing (the vertex module is freed when the fragment one fails) and the key is tried again on its next clear, at most kClearTries (3) times, with one log line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for picking this up. I already have an executed fault-injection fixture for #1787; I will hold my overlapping PR so we can consolidate the work here. I checked the actual factory/cache functions at
Is the three-attempt lifetime limit intended for ordinary transient allocation failures? After three failed calls, my probe makes allocation succeed on a later present, but this revision never calls the factory again. My candidate bounds attempts within a present and allows retry on a later present. The reusable source-executed fixture covers owning insertion, fragment allocation, temporary ownership and retry. Its runner currently extracts my candidate's failure-tracking state; the comparison adapts that state declaration to this revision without changing the factory. These are game-free allocation models, not a native OOM report. Happy to bring the executed coverage and rollback into this PR rather than duplicate it. |
…otRexed#1787) After kClearTries failures a key was left without its clear for the rest of the run, so a transient VK_ERROR_OUT_OF_DEVICE_MEMORY lost it for good. It now backs off instead: one try every kClearRetryEvery (600) of its clears, which keeps a driver that never makes the pipeline off the per-frame path and lets a device that recovered get the clear back. The source test checks the back-off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for checking it against the real functions. Retry after the third failure: fair point, fixed in fa04b6f. The cap is there so a pipeline the driver can never make (the #1787 case) is not rebuilt every frame, but it also shut out a transient
Happy to keep this as the one PR for #1787. If you'd rather your fixture land too, it could follow as a separate tests PR so this one stays small. |
|
Thanks, the back-off addresses the permanent lockout I reported. I checked the updated control flow at Agreed to keep #1787 in this PR. I will keep my overlapping candidate unpublished and won't open a separate tests-only PR. The host-allocation cases remain recorded separately; any broader allocation-failure policy should be agreed with the maintainers before extending this scope. |
A failed layout, shader module or pipeline in
clear_pipelinewas used or cached asVK_NULL_HANDLE, so one transient driver failure removed that masked clear for the rest of the run. Fixes #1787.Cause
clear_pipeline(gpu/vk/vk_draw.cpp) makes a masked clear's full-screen-triangle pipeline on its first use. It ignored whatvkCreatePipelineLayoutandvkCreateShaderModulereturned, so a failed layout or module went on into the next calls, and it stored whatevercached_graphicsgave back: a refused pipeline was cached asVK_NULL_HANDLE, and that clear never ran again.Change
VkResultis checked; a layout is only kept inclear_layoutonce it was made.kClearTries(3) times, then once everykClearRetryEvery(600) of its clears, so a driver that always refuses it costs no compile every frame and a device that was short of memory for a while gets the clear back; the third failure logs onevk: masked clear: no <step> (VkResult n)line. A key that succeeds drops its count.Test
tests/test_masked_clear_failure.py(game-free, reads the source liketest_mesh_fallback_failed_once.py): every creation's result is checked after the call, the bound is checked before any work, a failed pipeline is counted and never cached, and the vertex module is freed on the fragment failure. It fails onmainand passes here;python -I -B tests/run_all.pyis otherwise unchanged on Windows.Nothing changes on screen while the driver makes the pipeline, so no screenshots. Not run in the game: the path only matters when the driver refuses the pipeline.
🤖 Generated with Claude Code