The review of 2b9b3061 found that the check missed the dangerous regression. It only checked that each place that lets
something go calls vk_upscaler_let_go, so with destroy_size put back in vk_dlaa.c free_size, or hl_destroy in
hudless_from's size change, it still passed, while either frees images or a DLSS feature a frame still in flight uses.
The check now also fails when:
- a function that lets go of what the GPU may still use (vk_dlaa.c free_size, free_snap, stale_sizes, release_kept,
retire_idle, evaluate and the retire_size, retire_feat, retire_snap, retire_hl and retire_pb helpers; vk_ffx.cpp
context_for, trim, retire_up, vk_ffx_trim_idle and vk_ffx_release_idle; vk_ffx4.cpp context_for, vk_ffx4_trim,
retire_up and vk_ffx4_release_idle) calls a destroy that frees at once (destroy_size, destroy_snap, hl_destroy,
pb_destroy, feat_release, N.release, vkDestroyImageView, vmaDestroyImage; A.destroy in the FSR files);
- hudless_from, pb_images or snap_for call one of those before their first image2d call (after it, only their half-made
new images are destroyed);
- upd_take_all, which releases a whole list whatever its gates, is called outside teardown (vk_dlaa_release,
vk_ffx_release, vk_ffx4_release) and a full list's fallback (dead_put, the FSR files' retire_up), or there before
vk_upscaler_settle's wait for the device.
docs/building.md "Checks" says so.
Each of 19 mutations of scratch copies fails the check (destroy_size in free_size and retire_idle, hl_destroy in
hudless_from, pb_destroy in pb_images, destroy_snap in free_snap and snap_for, feat_release in release_kept, N.release in
stale_sizes, vmaDestroyImage in retire_size, upd_take_all in retire_hl, A.destroy in FSR 3.1's retire_up and in either
file's trim and release_idle, dead_put and FSR 4's retire_up without the settle, FSR 3.1 and FSR 4 without the retry);
the unchanged
sources pass, and stability-pass's sources fail with 46 problems. tools/check_content.py --staged passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>