Skip to content

AGC: host imports are not released before vkDestroyDevice (VUID-vkDestroyDevice-device-05137) #1236

Closed

Description

@awake-devel

Summary

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:

VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ctest --test-dir build -V

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

  1. added a commit that references this issue on Oct 7, 2026
    c411489
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions