-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Significant rendering lag when using Vulkan #2938
Comments
What does looking at the example However as many people are relying on the example app/backends we should aim at reducing those issues in them. Would need to investigate the Vulkan example, any help appreciated there! |
I get that some lag is inevitable, and I can see that when using OpenGL, but its much more significant when using Vulkan which surprises me. Given that this issue exists in both the example backend and imgui-wgpu-rs, I agree that it's probably still an issue outside the scope of imgui itself, but I haven't been able to find anything regarding high input latency particularly with Vulkan. Maybe I haven't been searching the right thing, though. |
If you find a solution it would be great if you post about it, but I'm afraid we can't really help here. Note that if you vsync you'll always get some form of lag between a hardware mouse cursor and normal GPU render path. Try to enable |
Not sure it's related to your problem, but I remember some of official Vulkan backends using |
Yeah, that's pretty much the solution I ended up on too. I'll leave this issue open for now if someone comes up with any other solution though. |
The comments above suggest changing the main.cpp of our example from:
Into
However I cannot get Mailbox to behave as expected here :( On my laptop with the Intel graphics card, only On same laptop with Nvidia with |
@ocornut As vulkan spec says, |
Would you be able to sugget minimum code in the Vulkan examples to use |
Maybe the simplest solution is just wait small amount of time after sending commands like this (from my own backend implementation): auto endTime = std::chrono::high_resolution_clock::now();
auto frameTime = (endTime - m_pimpl->lastTime);
auto frameTimeWindow = std::chrono::nanoseconds(1000000000) / m_pimpl->fps;
auto sleepTime = frameTimeWindow - frameTime;
if (sleepTime.count() > 0) {
m_pimpl->lastTime = endTime + sleepTime;
std::this_thread::sleep_for(sleepTime);
} else {
m_pimpl->lastTime = endTime;
} I'm not Vulkan expert so someone can propose better solution though. |
No this is never the right solution. Never introduce sleeps/waits in your production code people. I think Imgui and GLFW/Vulkan really have some synchronisation issues here. I already tried to disable double buffering ( Ps. I'm using Imgui for a GUI application, not a game. This issue is definitely related to: #1805 |
I thought this is an inherent flaw of Linux graphics stack. Windows and MacOS do not exhibit this behavior, and it is somewhat amortized on Linux if 144hz monitor is used. Experience is absolutely terrible with 60hz monitor however. |
Well that could be the case, but imgui is the only interface under Linux that lagg so much. Applications like Firefox, who are also using hardware acceleration doesn't suffer from all this under Linux... |
I em experiencing this in all applications. When refresh rate is set to 60hz, even dragging a desktop window produces a visible lag between position cursor grabbed on the window and actual mouse cursor position. Same is true for UI in other 3D applications. Likewise it gets much better with higher refresh rate. |
Totally forgot about this issue... I'm glad to say that I have found a real solution! The problem comes from blocking on acquiring the next swapchain image, losing window events during that period. In my case using |
@Rytone that is great to hear! Could you maybe add this fix to the Imgui glfw +opengl and/or glfw+vulkan example? That would be great for everybody! |
This issue will be fixable by using the VK_EXT_present_timing extension when it becomes available. As I understand it VK_EXT_present_timing allows for two things: scheduling a presentation time for an image, and understanding the actual time an image was presented. By knowing the pesentation time it is possible to build a rendering loop which optimally reduces input lag by dynamically adjusting the render loop timing to sample inputs and render the next frame just before it is presented. |
Here is my workaround. modified main.cpp
@@ -18,8 +18,9 @@
#include <SDL_vulkan.h>
#include <vulkan/vulkan.h>
#include <log/log.hpp>
+#include <chrono>
-//#define IMGUI_UNLIMITED_FRAME_RATE
+#define IMGUI_UNLIMITED_FRAME_RATE
#ifdef _DEBUG
#define IMGUI_VULKAN_DEBUG_REPORT
#endif
@@ -496,6 +497,9 @@ int main(int, char**)
// Main loop
bool done = false;
+
+ const auto TargetFps = 120;
+ auto t0 = std::chrono::high_resolution_clock::now();
while (!done)
{
// Poll and handle events (inputs, window resize, etc.)
@@ -503,14 +507,37 @@ int main(int, char**)
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
- SDL_Event event;
- while (SDL_PollEvent(&event))
+ t0 += std::chrono::microseconds(1'000'000 / TargetFps);
+ while (std::chrono::high_resolution_clock::now() < t0)
{
- ImGui_ImplSDL2_ProcessEvent(&event);
- if (event.type == SDL_QUIT)
+ const auto delay = std::chrono::duration_cast<std::chrono::milliseconds>(t0 - std::chrono::high_resolution_clock::now()).count();
+ if (delay < -200)
+ t0 = std::chrono::high_resolution_clock::now();
+ if (delay > 0)
+ {
+ SDL_Event event;
+ auto res = SDL_WaitEventTimeout(&event, delay);
+ if (res)
+ {
+ ImGui_ImplSDL2_ProcessEvent(&event);
+ if (event.type == SDL_QUIT)
done = true;
- if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
+ if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
done = true;
+ }
+ }
+ else
+ {
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ {
+ ImGui_ImplSDL2_ProcessEvent(&event);
+ if (event.type == SDL_QUIT)
+ done = true;
+ if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
+ done = true;
+ }
+ }
} |
Sadly it's still a problem on May, 2022. There are still perceivable mouse lag after enabling After disabling v-sync, framerate of the opengl backend can reach around 1000FPS and Direct12 2000FPS. Vulkan doesn't suffer from the lag issue but it's framerate can only reach 500FPS. Perhaps there are some errors inside the vulkan implementation. Here is my laptop setup: |
I'm trying to make a simple GUI application (not a game) based on Vulkan, GLFW and Dear ImGui for Windows 10. Faced the same issue, the interface can't keep up with the system cursor with severe lag. @ocornut is it possible to make imgui automatically switch the cursor to software mode when dragging UI elements? Also I don't think VK_EXT_present_timing can help. It will only give you a hint when the next presentation will happen, so you can adjust the time delta for the physics calculation (to avoid motion jitter at unstable framerates). But you won't know where the user will move the cursor at that point in time. |
@MrROBUST No satisfying solution really, but you could toggle the cursor mode like this, which does make the cursor stick to any dragged item, though the lag that is then occurred on the cursor is noticable, however less jarring. Somewhere early in the draw loop: io.MouseDrawCursor = ImGui::IsMouseDown(ImGuiMouseButton_::ImGuiMouseButton_Left); |
You can use github.com/ishitatsuyuki/LatencyFleX to minimize latency if |
Just found this issue (again) after having to deal with this super laggy behaviour on Linux (only). I used @rastertail 's solution and it works. Thanks. Imgui is hardly to blame here. It is a Vulkan oddity as @ocornut put it correctly. It is quite laughable from Vulkan's side in my opinion. The most basic things are quite hard to do and library maintainers (I have to maintain a Vulkan app myself for work) have to deal with these things all the time. I'd not even blame Omar for letting the Vulkan backends to die. I certainly would if I could. |
I'm not letting Vulkan backends to die but all those problems are generally more multi-faceted and difficult to find one right solution for than most people want to see or care about. So those issues generally gets stuck for a while until someone puts on the deep work. |
Didn't mean to put words in your mouth. If it made the impression, I'm sorry! It just reflects my frustration with the API. It went in the right direction but fails on so many things. I just tried an OpenGL 4.6 app (with imgui) that I had only running on Windows so far on Linux. It took me 5min to adjust come linker flags and it runs just as well as on Windows. Vulkan just fails at something like that from my experience. |
There are variety of issues with OpenGL drivers, it's equally a mess unfortunately :( Vulkan is just so much complicated, it's a shame IMHO there isn't a modern simple API . |
This still seems to be an issue and I agree that I'm sensing latency when using the Vulkan example, which I don't as much with e.g. DX11 example. Here are discussions which MIGHT be related. #2938 #3171 |
Version/Branch of Dear ImGui:
Version: 1.73, 1.75 WIP
Branch: master
Back-end/Renderer/Compiler/OS
Back-ends: Yatekii/imgui-wgpu-rs, imgui_impl_opengl3.cpp, imgui_impl_vulkan.cpp
Operating System: Arch Linux, awesomewm
My Issue/Question:
In my own application using imgui-wgpu-rs, I've noticed that there is a significant input lag for me on Linux, and wgpu uses Vulkan, so I tested further and I've been able to reproduce the issue with the OpenGL and Vulkan examples that are here. Inputs, particularly things like moving windows, are noticeably delayed when using Vulkan compared to with OpenGL.
Screenshots/Video
(left is Vulkan, right is OpenGL)
Standalone, minimal, complete and verifiable example:
examples/example_sdl_opengl3
examples/example_sdl_vulkan
The text was updated successfully, but these errors were encountered: