Skip to content

fix(vulkan): destroy the enable2 device only after xrDestroySession (runtime#1779) - #345

Merged
dfattal merged 1 commit into
DisplayXR:mainfrom
byungjul:fix/vk-teardown-order
Oct 2, 2026
Merged

dfattal merged 1 commit into
DisplayXR:mainfrom
byungjul:fix/vk-teardown-order

Conversation

@byungjul

@byungjul byungjul commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes the session-stop / quit crash reported as DisplayXR/displayxr-runtime#1779. The cause is in the plugin, not the runtime.

Problem

On Vulkan, every session stop (XRGeneralSettings.Instance.Manager.StopSubsystems()) and every app quit crashed with SIGSEGV. That made a session restart impossible on Linux.

A core dump against a runtime built with symbols shows two threads at the crash:

runtime repaint thread (crashing):
  vkQueuePresentKHR (libnvidia-glcore)
  comp_vk_native_target_present      comp_vk_native_target.cpp:3546
  vk_dp_weave_and_present            comp_vk_native_compositor.c:6392
  vk_repaint_thread                  comp_vk_native_compositor.c:7190

plugin, at the same moment:
  vkDestroyInstance
  dxr_pvk_destroy
  dxr_prov_session_stop
  GfxStop

dxr_prov_session_stop called dxr_pvk_destroy() before xrEndSession, and dxr_pvk_destroy() destroyed the VkDevice and VkInstance that we created through XR_KHR_vulkan_enable2. The session still runs on them. The runtime's repaint thread keeps presenting the last frame until xrEndSession, so it presented on a destroyed device.

Fix

The teardown is split in two:

  • dxr_pvk_destroy() destroys the bridges, overlays, fence and command pool. It still runs before xrEndSession.
  • dxr_pvk_destroy_device() is new. It destroys the device and instance after xrDestroySession and xrDestroyInstance.

Platforms: Vulkan backend only (ENABLE_VULKAN): Linux, and Windows with DISPLAYXR_VK_EXPERIMENTAL=1. No change on D3D11/D3D12/Metal.

Testing

Ubuntu 26.04, RTX 4090 Laptop, Leia DS1, installed runtime v2.21.11. App: the lenovo-avatar Linux player.

Test Before After
Quit (×3) SIGSEGV every time No crash, destroyed logged after the session
Session restart every 8 s for 50 s Crash on the first stop 4 restarts, each back to FOCUSED; no xrEndFrame error, no Xid
Session restart every 12 s with both HUDs and the Local2D bubble on — 4 restarts; each new session recreates the Local2D layer (session token 1 → 5) and both wsui slots, and the first Unity copy is recorded for all three. No errors

The last row is the restart check requested on #337 for the Local2D/wsui Vulkan paths.

🤖 Generated with Claude Code

…isplayXR/displayxr-runtime#1779)

dxr_prov_session_stop called dxr_pvk_destroy() before xrEndSession, and that
destroyed the VkDevice + VkInstance we created through XR_KHR_vulkan_enable2.
The session still runs on them: the runtime's repaint thread keeps presenting
the last frame until xrEndSession. Every session stop and every quit crashed
in vkQueuePresentKHR on that thread (SIGSEGV).

Split the teardown:
- dxr_pvk_destroy(): bridges, overlays, fence, command pool. Still before
  xrEndSession.
- dxr_pvk_destroy_device(): device + instance, after xrDestroySession and
  xrDestroyInstance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants