ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.78k stars 10.17k forks source link

Vulkan back-end crashes on Linux when I try to maximize/resize window #2626

Closed kindlychung closed 4 months ago

kindlychung commented 5 years ago
Dear ImGui 1.71 (17100)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201703
define: __linux__
define: __GNUC__=8
--------------------------------
io.BackendPlatformName: imgui_impl_sdl
io.BackendRendererName: imgui_impl_vulkan
io.ConfigFlags: 0x00000000
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.BackendFlags: 0x0000000E
 HasMouseCursors
 HasSetMousePos
 RendererHasVtxOffset
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Operating System: Ubuntu 19.04

My Issue/Question:

Imgui crashes when I try to maximize/resize window:

Xlib:  extension "NV-GLX" missing on display ":0".
VkResult -1000001004

Standalone, minimal, complete and verifiable example: (see https://github.com/ocornut/imgui/issues/2261)

See example_sdl_vulkan.

ocornut commented 5 years ago

Could either be a problem with the Vulkan back-end, either a problem with your Linux setup/driver.

kindlychung commented 5 years ago

The "NV-GLX" issue is solved by switching to a X11 session from wayland. The crash still happens as before.

Call frames from a debugging session:

image

kindlychung commented 5 years ago

Suboptimal or out-of-date swap chain

Now we just need to figure out when swap chain recreation is necessary and call our new recreateSwapChain function. Luckily, Vulkan will usually just tell us that the swap chain is no longer adequate during presentation. The vkAcquireNextImageKHR and vkQueuePresentKHR functions can return the following special values to indicate this.

VK_ERROR_OUT_OF_DATE_KHR: The swap chain has become incompatible with the surface and can no longer be used for rendering. Usually happens after a window resize.

mocabe commented 5 years ago

The problem is vulkan examples don't handle vkAcquireNextImageKHR and vkQueuePresentKHR correctly. Both operation can fail when surface become outdated, and rebuilding swapchain does not guarantee next vkAcquireNextImageKHR's success. In my limited experience, the easiest way to handle vkAcquireNextImageKHR is just use while loop and rebuild swapchain until it matches current surface (don't forget using VkFence since vkAcquireNextImageKHR can be non-blocking).
We can just ignore when vkQueuePresentKHR returned out-of-date error.

ebachard commented 4 years ago

Hello,

Testing with the last changes did not work. And because the proc load was too high, I added an SDL_Delay(16) at the end of the main loop. Curiously, it was possible to resize the window without the boring instant crash. After some tests, after 2 or 3tries,I got no crash, and SDL_Delay(17), means any value > 16 works well.

Looks like some race condition with SDL resize window event or something like that ?

My machine : Linux / Intel x86_64, SDL2 2.0.9 + vulkan

The change,for the one interested to test is a one liner

diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp
index c4e529e1..8078471d 100644
--- a/examples/example_sdl_vulkan/main.cpp
+++ b/examples/example_sdl_vulkan/main.cpp
@@ -508,6 +508,8 @@ int main(int, char**)
         FrameRender(wd);

         FramePresent(wd);
+
+        SDL_Delay(17);
     }

     // Cleanup

Last but not least, I got the same instant crash when resizing the GLFW + vullkan window. I don't know well GLFW API, but couldn't this be the same timing issue ?

HTH

EDIT: added missing information :

Dear ImGui 1.75 WIP (17401)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201103
define: __linux__
define: __GNUC__=7
--------------------------------
io.BackendPlatformName: imgui_impl_sdl
io.BackendRendererName: imgui_impl_vulkan
io.ConfigFlags: 0x00000000
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigWindowsMemoryCompactTimer = 60.0f
io.BackendFlags: 0x0000000E
 HasMouseCursors
 HasSetMousePos
 RendererHasVtxOffset
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,256
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Other helpful information : Like other guys following the issue, I'm searching since a long while, and must add that I learned a lot about vulkan API, and did a lot of tests reading this very comprehensive page: https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#swapchain-image-acquire-and-present

[EDIT] : SDL_Delay of 16 ms does not work every time. After some tries, 17 gives better results (20 always works)

ebachard commented 4 years ago

Little update :

Using -DIMGUI_UNLIMITED_FRAME_RATE at build time + SDL_Delay(5) gives ~ 178 fps, and SDL_Delay(3) produces ~ 280 fps (using metrics in the demo), while SDL_Delay(2) gave me somecrashes. Perfect for my needs.

Looks like it works better (I was not able to make it crash again with SDL_Delay values > 2) :-)

Can someone confirm there is no more crash ?

The changes :

diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp
index c4e529e1..dbe41593 100644
--- a/examples/example_sdl_vulkan/main.cpp
+++ b/examples/example_sdl_vulkan/main.cpp
@@ -508,6 +514,7 @@ int main(int, char**)
         FrameRender(wd);

         FramePresent(wd);
+        SDL_Delay(5);  // SDL_Delay(3) should be the limit without seeing crash
     }

     // Cleanup
mocabe commented 4 years ago

@ebachard As I said, that crash comes from incorrect usage of Vulkan API in renderer code. Your workaround might work for some people, but broken codes are still broken after all.

ebachard commented 4 years ago

@mocabe : I never said it was the solution. My urgent need is to test Vulkan API with my software, without crash every time I move or resize the window. Since I'm curious to fix it correctly, be sure I'll continue to learn Vulkan API and make some tries from time to time ;-)

go2sh commented 4 years ago

This is not only limitted to the sdl backend, it also hits the glfw backend.

go2sh commented 4 years ago

And see https://vulkan-tutorial.com/Drawing_a_triangle/Swap_chain_recreation for handling.

RoryO commented 4 years ago

I have a raw X11 & Vulkan impl up for review #3372 . It handles window resizing properly. The current imgui example implementations for vulkan don't handle resized windows well. The best place to handle vulkan surface resizing is presenting the current swapchain to the surface and checking for vk_err_out_of_date. If you try and do it elsewhere, like responding to a window resize event, there's the possibility that it becomes out of date again from responding to that event to the next frame render loop by further resizing. This happens quite a bit when using an x11 compositor as they usually try to redraw the surface as the window resizes to make it look nicer.

mcallaghan-geotab commented 2 years ago

Similar?

Probably way different (since this issue is so old)

[96035:96043:0302/112205.248143:ERROR:vulkan_swap_chain.cc(441)] : vkAcquireNextImageKHR() hangs.
[96035:96035:0302/112205.248352:ERROR:gpu_service_impl.cc(964)] : Exiting GPU process because some drivers can't recover from errors. GPU process will restart shortly.

Version 98.0.4758.102 (Official Build) (64-bit)

$ vainfo
libva info: VA-API version 1.13.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_13
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.13 (libva 2.13.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 21.4.1 (be92568)
ocornut commented 4 months ago

I believe this should now be fixed, see this comment: https://github.com/ocornut/imgui/pull/3390#issuecomment-2098519110

Given the complexity of this and how it has been stretched over a long time (with other Vulkan changes), I would appreciate if everyone affected could confirm that it fixes the situation for them. Thanks everyone! If there is an issue please comment and we can reopen issues.