fix(vk): the presenter thread is off by default again #2544

Merged
hckrman101 merged 1 commit from fix/present-thread-off into main 2026-11-11 22:49:50 +00:00
hckrman101 commented 2026-11-11 22:46:58 +00:00 (Migrated from github.com)

A review of the presenter thread merged in #2325 found two problems that make it unsafe as a default, so this turns it off again until they are fixed.

  • The swapchain is used from two threads with no lock between them. The game thread's vkAcquireNextImageKHR runs while the presenter thread calls vkQueuePresentKHR and vkWaitForPresentKHR on the same swapchain. All three need the swapchain externally synchronized. The overlap happens every frame, by design.
  • The drain before a swapchain remake gives up after 5 s. Its callers then destroy the swapchain and semaphores the presenter may still be using. The presenter's own worst case (the copy's fence for 5 s, then the present) is longer than that. The same limit in present_out lets two presents go out of order.

What changes

  • RX_VK_PRESENT_THREAD is off unless set to 1. Off, the device makes no queue for the presenter, so the device and the presents are as they were before #2325.
  • The docs row and tests/test_present_thread.py say it is off by default. The test also checks that no queue is made for it while it is off.

The fixes (one lock or an idle wait around the swapchain's acquire and present, a drain that never gives up and leaves the swapchain alone, and the smaller findings) follow in their own PR. That PR turns the default back on only if every fix holds and is tested.

Tested: tests/test_present_thread.py, tests/test_fps_stats.py and tests/test_present_semaphores.py pass, and the Vulkan back end builds.

A review of the presenter thread merged in #2325 found two problems that make it unsafe as a default, so this turns it off again until they are fixed. - **The swapchain is used from two threads with no lock between them.** The game thread's `vkAcquireNextImageKHR` runs while the presenter thread calls `vkQueuePresentKHR` and `vkWaitForPresentKHR` on the same swapchain. All three need the swapchain externally synchronized. The overlap happens every frame, by design. - **The drain before a swapchain remake gives up after 5 s.** Its callers then destroy the swapchain and semaphores the presenter may still be using. The presenter's own worst case (the copy's fence for 5 s, then the present) is longer than that. The same limit in `present_out` lets two presents go out of order. ## What changes - `RX_VK_PRESENT_THREAD` is off unless set to `1`. Off, the device makes no queue for the presenter, so the device and the presents are as they were before #2325. - The docs row and `tests/test_present_thread.py` say it is off by default. The test also checks that no queue is made for it while it is off. The fixes (one lock or an idle wait around the swapchain's acquire and present, a drain that never gives up and leaves the swapchain alone, and the smaller findings) follow in their own PR. That PR turns the default back on only if every fix holds and is tested. Tested: `tests/test_present_thread.py`, `tests/test_fps_stats.py` and `tests/test_present_semaphores.py` pass, and the Vulkan back end builds.
Commenting is not possible because the repository is archived.
No description provided.