yshui / picom

A lightweight compositor for X11 with animation support
https://picom.app/
Other
4.18k stars 589 forks source link

vsync limits rendering to 60fps when both a 60hz and 144hz monitor is used #1027

Closed AlexAegis closed 1 year ago

AlexAegis commented 1 year ago

Platform

Arch Linux x86_64 Linux 6.1.12-arch1-1

GPU, drivers, and screen setup

Card: Nvidia RTX3080Ti Driver: nvidia 525.89.02-3 Setup: 2 27 inch 4K screens side by side, one 60 hz connected via DP port on the left, one 144hz with hdmi on the right (Set as primary display). And there is a 4K 60hz TV also plugged in using hdmi to mirror the left. And a Valve Index also taking up an hdmi slot, but it's off.

This might be relevant because the left DP monitor has higher priority (I guess it's an internal preference of the GPU) and everything thinks it's the primary monitor until my X config loads which tells it that my primary monitor is on hdmi, with a bigger refresh rate.

(My right, 144hz monitor is my newer monitor and hdmi is need to be able to fully utilize it, but I don't have any more hdmi at the back because. So no I can't reconfigure the cable. )

glxinfo -B:

name of display: :0
display: :0  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: 10099 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 525.89.02
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 525.89.02
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 525.89.02
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20

Environment

picom version

vgit-cee12
Diagnostics ```sh **Version:** vgit-cee12 ### Extensions: * Shape: Yes * RandR: Yes * Present: Present ### Misc: * Use Overlay: No (Another compositor is already running) * Config file used: /home/alex/.config/picom/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 ```conf backend = "glx" glx-no-stencil = true glx-copy-from-front = false glx-no-rebind-pixmap = true; shadow = true shadow-radius = 45 shadow-offset-x = -45 shadow-offset-y = -45 shadow-opacity = 0.25 shadow-exclude = [ "! name~=''", "name = 'Notification'", "name = 'Plank'", "name = 'Docky'", "name = 'Kupfer'", "name = 'xfce4-notifyd'", "name *= 'VLC'", "name *= 'compton'", "name *= 'picom'", "name *= 'Chromium'", "name *= 'Chrome'", "class_g = 'Firefox' && argb", "class_g = 'Conky'", "class_g = 'Kupfer'", "class_g = 'plasmashell'", "class_g = 'Synapse'", "class_g ?= 'Notify-osd'", "class_g ?= 'Cairo-dock'", "class_g ?= 'Xfce4-notifyd'", "class_g ?= 'Xfce4-power-manager'", "_GTK_FRAME_EXTENTS@:c", "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'", "name *= 'polybar'" ] blur_exclude = [ "name *= 'polybar'" ] shadow-ignore-shaped = true inactive-opacity = 1 active-opacity = 1 frame-opacity = 0.95 inactive-opacity-override = false opacity-rule = [ "85:class_g = 'Spotify' && focused", "60:class_g = 'Spotify' && !focused" ]; blur-background = true; blur-background-frame = false; blur-background-fixed = false; blur-method = "dual_kawase"; blur-size = 30; blur-deviation = 100.0; blur-strength = 14; blur-kern = "3x3box"; glx-no-stencil = true; fading = true fade-delta = 6 fade-in-step = 0.03 fade-out-step = 0.03 fade-exclude = [ ] mark-wmwin-focused = true mark-ovredir-focused = true use-ewmh-active-win = true detect-rounded-corners = true detect-client-opacity = true vsync = true dbe = false unredir-if-possible = false focus-exclude = [ ] detect-transient = true detect-client-leader = true 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 } } xrender-sync-fence = true ```
/etc/X11/xorg.conf ```conf # nvidia-settings: X configuration file generated by nvidia-settings # nvidia-settings: version 525.89.02 Section "ServerLayout" Identifier "Layout0" Screen 0 "Screen0" 0 0 InputDevice "Keyboard0" "CoreKeyboard" InputDevice "Mouse0" "CorePointer" Option "Xinerama" "0" EndSection Section "Files" EndSection Section "InputDevice" # generated from default Identifier "Mouse0" Driver "mouse" Option "Protocol" "auto" Option "Device" "/dev/psaux" Option "Emulate3Buttons" "no" Option "ZAxisMapping" "4 5" EndSection Section "InputDevice" # generated from default Identifier "Keyboard0" Driver "kbd" EndSection Section "Monitor" # HorizSync source: edid, VertRefresh source: edid Identifier "Monitor0" VendorName "Unknown" ModelName "LG Electronics LG Ultra HD" HorizSync 135.0 - 135.0 VertRefresh 40.0 - 61.0 Option "DPMS" EndSection Section "Device" Identifier "Device0" Driver "nvidia" VendorName "NVIDIA Corporation" BoardName "NVIDIA GeForce RTX 3080 Ti" EndSection Section "Screen" Identifier "Screen0" Device "Device0" Monitor "Monitor0" DefaultDepth 24 Option "Stereo" "0" Option "nvidiaXineramaInfoOrder" "DFP-2" Option "metamodes" "DP-2: 3840x2160_60 +0+0, HDMI-1: 3840x2160_60 +7680+0, HDMI-0: 3840x2160_144 +3840+0; DP-2: nvidia-auto-select +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 3840x2160_30 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 2560x1440 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1920x1080 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1920x1080_60_0 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1600x900 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1280x1024 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1280x800 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1280x720 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1280x720_60_0 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1152x864 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 1024x768 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 800x600 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 720x480 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 640x480 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: 640x480_60_0 +0+0, HDMI-0: nvidia-auto-select +0+0; DP-2: nvidia-auto-select +0+0 {viewportin=2560x1600, viewportout=3456x2160+192+0}, HDMI-0: nvidia-auto-select +0+0; DP-2: nvidia-auto-select +0+0 {viewportin=1920x1200, viewportout=3456x2160+192+0}, HDMI-0: nvidia-auto-select +0+0; DP-2: nvidia-auto-select +0+0 {viewportin=1680x1050, viewportout=3456x2160+192+0}, HDMI-0: nvidia-auto-select +0+0; DP-2: nvidia-auto-select +0+0 {viewportin=1600x1200, viewportout=2880x2160+480+0}, HDMI-0: nvidia-auto-select +0+0; DP-2: nvidia-auto-select +0+0 {viewportin=1440x900, viewportout=3456x2160+192+0}, HDMI-0: nvidia-auto-select +0+0; DP-2: nvidia-auto-select +0+0 {viewportin=1366x768, viewportout=3840x2158+0+1}, HDMI-0: nvidia-auto-select +0+0" Option "SLI" "Off" Option "MultiGPU" "Off" Option "BaseMosaic" "off" SubSection "Display" Depth 24 EndSubSection EndSection ```

Steps of reproduction

  1. Enable vsync

Expected behavior

Windows move smoothly at 144fps on 144hz screens and 60fps on 60hz screens

Current Behavior

With vsync = true both displays render 60 fps. Only when turning vsync = false it behaves like it should. I notice no tearing so I'll continue to use picom with vsync off to enable 144hz.

absolutelynothelix commented 1 year ago

that's a good question how it all should work when a user has multiple monitors with different refresh rates. talking only about gl-powered backends (glx, egl): afaik currently we have a single gl context that maintains the screen - a rectangle on which all monitor's regions are mapped - and it's updated at some refresh rate hence all monitors are. afaiu we can have multiple gl contexts for each monitor so they'll be updated at their refresh rates but i believe that implementing this isn't trivial and will introduce a lot of bugs and weird things. not sure about other solutions.

REALERvolker1 commented 1 year ago

This is a bug in x11 itself. X11 basically treats a multi-monitor setup on one GPU as a single big display. When you have multiple monitors with different refresh rates, it defaults to the lowest refresh rate.

I use picom with vsync = true on a laptop with an Nvidia GPU and an intel iGPU. When I have my external monitor plugged into the USB-C port attached to my iGPU, I have the same exact issue, but when I plug it into the port attached to my dGPU, my laptop monitor runs at 144hz just fine, because it is on a different GPU, for reasons I don't understand. How is your hardware setup in this regard? Are all your monitors plugged into the same GPU?

yshui commented 1 year ago

Right this is most likely a X limitation. picom doesn't really control the refresh rate, it just enables vsync and let the vsync mechanism decide.

Closing as there is nothing we can realistically do.

sersorrel commented 1 year ago

fwiw, I was running into this, but seem to have "fixed" it (that is, vsync is now synced to my 75hz monitors rather than my 60hz monitor) by enabling the AsyncFlipSecondaries Xorg option (see modesetting(4) for details).