You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AGC: host imports are not released before vkDestroyDevice (VUID-vkDestroyDevice-device-05137) #1236
VulkanDevice::State::~State releases the device's caches before vkDestroyDevice (VulkanDevice.cpp#L481-L556), the image mirrors included since #849, but not the host imports. The import registry, Imports(), is a function-local static, so every import still registered when the device is destroyed keeps its VkBuffer and VkDeviceMemory past vkDestroyDevice. The validation layer reports it as VUID-vkDestroyDevice-device-05137.
The registry frees leftover imports only when it next sees another device (refreshImports), through the handle it stored for the old one. The replacement at the first flip is safe, since #59 keeps replaced devices alive (Presentation.cpp#L59). A process that destroys its device and then creates another would free them through a destroyed VkDevice; no test does that today.
Found with AI assistance (Claude Code) while running the suite under the validation layer for #1221.
Evidence
main at cea1ef1, Linux, GTX 1050 Ti Max-Q (NVIDIA 580.178.04), vulkan-validation-layers 1.4.363.0, core validation:
All 400 tests pass. 23 execution tests report one VUID-vkDestroyDevice-device-05137 each and nothing else: bvh64_intersect_ray, flat_cache_bits, flat_d16_loads, flat_loads, flat_loads_x2_x3, flat_loads_x4, flat_store, global_atomic_csub, global_atomics, global_atomics64, global_atomics_float, global_atomics_lanes, global_loads, global_loads_x2_x3, global_loads_x4, global_store_addtid, global_vcc_base, image_converted_unorm, image_srgb_load, image_store_packed, image_store_sint, scalar_wide_loads and view_past_last_mip (all agc_driver_*).
Each leaks one or two VkBuffer/VkDeviceMemory pairs. Printing the handles at the end of createImport matches them to imports: flat_store makes three, one of 16 KiB and two of 64 KiB, and the two 64 KiB ones are its 4 leaked objects; the 16 KiB one is released during the test. flat_loads leaks its one 64 KiB import.
vkDestroyDevice(): VkDevice 0x… has 4 leaked objects that have not been destroyed.
VkDeviceMemory 0x150000000015, VkDeviceMemory 0x170000000017, VkBuffer 0x140000000014, VkBuffer 0x160000000016
Proposed fix
A ClearHostImports(VkDevice) beside ClearImageMirrors: under the registry lock, if the registry belongs to the device, destroy each import's buffer and memory (and unmap its alias on Windows), clear imports and failed, reset device and bump epoch. ~State calls it right after ClearImageMirrors (L523), once the recorder, the resource cache and copiedWriters, which can still reference imports, are gone.
Tried locally: the 23 reports disappear, and the full suite passes 400/400 under the layer with no validation message.
Activity
fix(agc): release host imports before the device is destroyed