Skip to content
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

Lag when pressing keys in Vulkan application. #1232

Open
mcourteaux opened this issue Apr 4, 2024 · 8 comments
Open

Lag when pressing keys in Vulkan application. #1232

mcourteaux opened this issue Apr 4, 2024 · 8 comments

Comments

@mcourteaux
Copy link

mcourteaux commented Apr 4, 2024

Platform

Ubuntu 22.04.3 LTS / 6.5.0-26-generic

GPU, drivers, and screen setup

NVIDIA RTX 3080Ti with Driver 535.154.05 CUDA Version: 12.2
Two monitors side-by-side, left one rotated 90 degrees (xrandr).

name of display: :1
display: :1  screen: 0
direct rendering: Yes
Memory info (GL_NVX_gpu_memory_info):
    Dedicated video memory: 12288 MB
    Total available memory: 12288 MB
    Currently available dedicated video memory: 9256 MB
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce RTX 3080 Ti/PCIe/SSE2
OpenGL core profile version string: 4.6.0 NVIDIA 535.154.05
OpenGL core profile shading language version string: 4.60 NVIDIA
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

OpenGL version string: 4.6.0 NVIDIA 535.154.05
OpenGL shading language version string: 4.60 NVIDIA
OpenGL context flags: (none)
OpenGL profile mask: (none)

OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 535.154.05
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20

Environment

i3

picom version

vgit-d8c34

Diagnostics

Version: vgit-d8c34

Extensions:

  • Shape: Yes
  • RandR: Yes
  • Present: Present

Misc:

  • Use Overlay: No
    (Another compositor is already running)
  • Config file used: /home/martijn/.config/picom.conf

Drivers (inaccurate):

NVIDIA

Backend: glx

  • Driver vendors:
  • GLX: NVIDIA Corporation
  • GL: NVIDIA Corporation
  • GL renderer: NVIDIA GeForce RTX 3080 Ti/PCIe/SSE2

Backend: egl

  • Driver vendors:
  • EGL: NVIDIA
  • GL: NVIDIA Corporation
  • GL renderer: NVIDIA GeForce RTX 3080 Ti/PCIe/SSE2

Configuration:

Configuration file
#################################
#
# Backend
#
#################################

# Backend to use: "xrender" or "glx".
# GLX backend is typically much faster but depends on a sane driver.
backend = "glx";

#################################
#
# GLX backend
#
#################################

glx-no-stencil = true;

use-damage = true;

# GLX backend: Avoid rebinding pixmap on window damage.
# Probably could improve performance on rapid window content changes, but is known to break things on some drivers (LLVMpipe).
# Recommended if it works.
glx-no-rebind-pixmap = true;


#################################
#
# Shadows
#
#################################

# Enabled client-side shadows on windows.
shadow = true;
# Don't draw shadows on DND windows.
no-dnd-shadow = true;
# Avoid drawing shadows on dock/panel windows.
no-dock-shadow = true;
# The blur radius for shadows. (default 12)
shadow-radius = 9;
# The left offset for shadows. (default -15)
shadow-offset-x = -5;
# The top offset for shadows. (default -15)
shadow-offset-y = -5;
# The translucency for shadows. (default .75)
shadow-opacity = 0.6;

# Set if you want different colour shadows
# shadow-red = 0.0;
# shadow-green = 0.0;
# shadow-blue = 0.0;

# The shadow exclude options are helpful if you have shadows enabled. Due to the way compton draws its shadows, certain applications will have visual glitches
# (most applications are fine, only apps that do weird things with xshapes or argb are affected).
# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher.
shadow-exclude = [
    "! name~=''",
    "name = 'Notification'",
    "name = 'Plank'",
    "name = 'Docky'",
    "name = 'Kupfer'",
    "name = 'xfce4-notifyd'",
    "name *= 'VLC'",
    "name *= 'compton'",
    "name *= 'Chromium'",
    "name *= 'Chrome'",
    "name *= 'Firefox'",
    "class_g = 'launcher.exe'",
    "class_g = 'Conky'",
    "class_g = 'Kupfer'",
    "class_g = 'Synapse'",
    "class_g ?= 'Notify-osd'",
    "class_g ?= 'Cairo-dock'",
    "class_g ?= 'Xfce4-notifyd'",
    "class_g ?= 'Xfce4-power-manager'"
];
# Avoid drawing shadow on all shaped windows (see also: --detect-rounded-corners)
shadow-ignore-shaped = false;

#################################
#
# Opacity
#
#################################

inactive-opacity = 1;
active-opacity = 1;
frame-opacity = 1;
inactive-opacity-override = false;

# Dim inactive windows. (0.0 - 1.0)
# inactive-dim = 0.2;
# Do not let dimness adjust based on window opacity.
# inactive-dim-fixed = true;
# Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred.
# blur-background = true;
# Blur background of opaque windows with transparent frames as well.
# blur-background-frame = true;
# Do not let blur radius adjust based on window opacity.
#blur-background-fixed = false;
blur-background-exclude = [
    "window_type = 'dock'",
    "window_type = 'desktop'"
];

blur:
{
  method = "dual_kawase";
  strength = 6;
};


#################################
#
# Fading
#
#################################

# Fade windows during opacity changes.
fading = true;
# The time between steps in a fade in milliseconds. (default 10).
fade-delta = 4;
# Opacity change between steps while fading in. (default 0.028).
fade-in-step = 0.03;
# Opacity change between steps while fading out. (default 0.03).
fade-out-step = 0.03;
# Fade windows in/out when opening/closing
# no-fading-openclose = true;

# Specify a list of conditions of windows that should not be faded.
fade-exclude = [ ];

#################################
#
# Other
#
#################################

# Try to detect WM windows and mark them as active.
mark-wmwin-focused = true;
# Mark all non-WM but override-redirect windows active (e.g. menus).
mark-ovredir-focused = true;
# Use EWMH _NET_WM_ACTIVE_WINDOW to determine which window is focused instead of using FocusIn/Out events.
# Usually more reliable but depends on a EWMH-compliant WM.
use-ewmh-active-win = true;
# Detect rounded corners and treat them as rectangular when --shadow-ignore-shaped is on.
detect-rounded-corners = true;

# Detect _NET_WM_OPACITY on client windows, useful for window managers not passing _NET_WM_OPACITY of client windows to frame windows.
# This prevents opacity being ignored for some apps.
# For example without this enabled my xfce4-notifyd is 100% opacity no matter what.
detect-client-opacity = true;

# Set VSync method. VSync methods currently available:
# none: No VSync
# drm: VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some drivers.
# opengl: Try to VSync with SGI_video_sync OpenGL extension. Only work on some drivers.
# opengl-oml: Try to VSync with OML_sync_control OpenGL extension. Only work on some drivers.
# opengl-swc: Try to VSync with SGI_swap_control OpenGL extension. Only work on some drivers. Works only with GLX backend. Known to be most effective on many drivers. Does not actually control paint timing, only buffer swap is affected, so it doesn’t have the effect of --sw-opti unlike other methods. Experimental.
# opengl-mswc: Try to VSync with MESA_swap_control OpenGL extension. Basically the same as opengl-swc above, except the extension we use.
# (Note some VSync methods may not be enabled at compile time.)
vsync = true;

# Enable DBE painting mode, intended to use with VSync to (hopefully) eliminate tearing.
# Reported to have no effect, though.
dbe = false;

# Specify a list of conditions of windows that should always be considered focused.
focus-exclude = [ ];

# Use WM_TRANSIENT_FOR to group windows, and consider windows in the same group focused at the same time.
detect-transient = true;
# Use WM_CLIENT_LEADER to group windows, and consider windows in the same group focused at the same time.
# WM_TRANSIENT_FOR has higher priority if --detect-transient is enabled, too.
detect-client-leader = true;

#################################
#
# Window type settings
#
#################################

wintypes:
{
    tooltip =
    {
        # fade: Fade the particular type of windows.
        fade = true;
        # shadow: Give those windows shadow
        shadow = false;
        # opacity: Default opacity for the type of windows.
        opacity = 0.85;
        # focus: Whether to always consider windows of this type focused.
        focus = true;
    };
};

Steps of reproduction

Unfortunately, reproducing it is not easy. I'm using bgfx in my application with the Vulkan backend, and I have Tracy hooked up profiling everything. Whenever I press a key (even one that has absolutely no effect), I get a very slow vkQueuePresentHKR call. This causes the frame time to be around 28ms and the next frame then catches up and gets completed in ~5ms, causing the result to be fine. I don't believe any frames are dropped. I do notice the huge slowdown in my application which of course is not great for timing and predictable handling of user input. This also effectively reduces my frame time budget to 5ms instead of 16ms. If I don't hit the 5ms deadline when pressing a key, I'll drop a frame.

image

In the above image, the problem happens in the frame in the middle of the picture.
I have no clue what this has to do with Picom, but if I exit Picom, the problem disappears:

image

I'm pressing keys several times here in this screenshot, and no delay is observed. (The spurious long frames is simply because my application doesn't render continuously, but only upon animations. The screenshots are taken in regions of animation where I press keys.)

Note that this does not occur with mouse events.

In summary, this only happens with the combination of: picom + vulkan app with PRESENT_MODE_FIFO_KRH + keypresses.
The issue disappears in all of the following situations:

  • stop picom, or
  • switch to OpenGL backend for my application, or
  • use vulkan with PRESENT_MODE_IMMEDIATE_KRH, or
  • produce mouse events.
@absolutelynothelix
Copy link
Collaborator

what present mode do you use in your vulkan application?

@mcourteaux
Copy link
Author

what present mode do you use in your vulkan application?

It's VK_PRESENT_MODE_FIFO_KHR.

@absolutelynothelix
Copy link
Collaborator

does changing it to the VK_PRESENT_MODE_IMMEDIATE_KHR one fix the issue?

@mcourteaux
Copy link
Author

Yes, it does! Interesting. However, now I'm producing frames every ~3 to ~4ms. So my framerate is effectively around 250 FPS. The vsync mechanism seems to be not functioning with that mode.

@absolutelynothelix
Copy link
Collaborator

The vsync mechanism seems to be not functioning with that mode.

indeed, because the VK_PRESENT_MODE_IMMEDIATE_KHR present mode disables vsync.

i'm afraid that your original issue may be related to the well-known long-standing nvidia's driver issue with the VK_PRESENT_MODE_FIFO_KHR present mode and there's nothing to do with picom. for example, i have issues with sample vulkan apps that use the VK_PRESENT_MODE_FIFO_KHR present mode like vkcube on an nvidia gpu even without a compositor. if you won't be able to reproduce your original issue on an amd or intel gpu then my guess is correct.

@mcourteaux
Copy link
Author

I can replicate the findings from the linked forum on my machine as well, but the fact that my problem is keystroke related, happens 100% of the time, and after all my testing, only occurs with picom, I'm not so sure that there is not something going on with picom.

I figured out that this problem is happening when I press keys when other windows are focused. Not all, but some. For example pressing no-effect keys when Tracy is focused, also causes the frame time to jump up to 50ms in my app. A second instance of my app is also good to trigger the effect: run my app twice, press keys in any instance, and observe slowdowns in both.

When testing the complaints in the forum you linked, I also found out that upon every window focus switch in i3 (by means of moving the mouse from one to the other for example), causes a similar high frame time.

The key presses causing this sounds so ridiculous to me. I can't think of anything that could be related to key presses.

@mcourteaux
Copy link
Author

if you won't be able to reproduce your original issue on an amd or intel gpu then my guess is correct.

I might try to use Nouveau drivers tomorrow to see if that changes anything.

@nmcveity
Copy link

I also see this issue, though profiling shows that the vkQueuePresentHKR call will take 0.05 seconds - so you can easily see the dropped frames. Strangely it's not just a key press/release event that is correlated to the stutter, but if you press and hold then key repeat events also cause it.

My setup slightly different: Debian 12, Regolith/i3, NVIDIA GeForce GTX 1050 Ti/PCIe/SSE2, Driver 535.161.08.

Switching my compositor from picom to xcompmgr and the problem disappears entirely.

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

No branches or pull requests

3 participants