RadeonSI: gbm_surface_lock_front_buffer() after eglSwapBuffers() returns old buffer with mesa_glthread=true
System information
System:
Host: thinkbook Kernel: 6.5.4-arch2-1 arch: x86_64 bits: 64 compiler: gcc
v: 13.2.1 Desktop: KDE Plasma v: 5.27.8 tk: Qt v: 5.15.10 wm: kwin_wayland
dm: SDDM Distro: Arch Linux
CPU:
Info: 8-core model: AMD Ryzen 7 5700U with Radeon Graphics bits: 64
type: MT MCP arch: Zen 2 rev: 1 cache: L1: 512 KiB L2: 4 MiB L3: 8 MiB
Speed (MHz): avg: 1811 high: 4372 min/max: 400/4372 boost: enabled cores:
1: 1114 2: 4372 3: 4372 4: 1114 5: 2349 6: 1114 7: 1114 8: 1114 9: 1269
10: 1114 11: 1114 12: 1114 13: 1114 14: 1114 15: 1114 16: 4372
bogomips: 57506
Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm
Graphics:
Device-1: AMD Lucienne vendor: Lenovo driver: amdgpu v: kernel arch: GCN-5
pcie: speed: 8 GT/s lanes: 16 ports: active: eDP-1 empty: DP-1,DP-2,HDMI-A-1
bus-ID: 05:00.0 chip-ID: 1002:164c temp: 39.0 C
Device-2: IMC Networks Integrated Camera driver: uvcvideo type: USB
rev: 2.0 speed: 480 Mb/s lanes: 1 bus-ID: 1-3:2 chip-ID: 13d3:56ff
Display: wayland server: X.org v: 1.21.1.8 with: Xwayland v: 23.2.1
compositor: kwin_wayland driver: X: loaded: modesetting
alternate: fbdev,vesa dri: radeonsi gpu: amdgpu display-ID: 0
Monitor-1: eDP-1 res: 1920x1080 size: N/A
API: OpenGL v: 4.6 Mesa 23.1.8-arch1.1 renderer: AMD Radeon Graphics
(renoir LLVM 16.0.6 DRM 3.54 6.5.4-arch2-1) direct-render: Yes
Describe the issue
Note: I'm only describing the symptoms as I can observe them, the main cause is maybe somewhere else.
Kodi with the GBM backend is showing graphical corruptions/tearing since RadeonSI defaults mesa_glthread to true. This was previously reported in #7977 and #9115. I debugged and found out the the issue is that after an eglSwapBuffers
a gbm_surface_lock_front_buffer
often still returns the old front buffer.
The issue can easily be reproduced with kmscube (which also shows tearing) after applying this patch:
--- a/drm-legacy.c
+++ b/drm-legacy.c
@@ -22,6 +22,7 @@
*/
#include <errno.h>
+#include <gbm.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
@@ -97,6 +98,9 @@ static int legacy_run(const struct gbm *gbm, const struct egl *egl)
if (gbm->surface) {
eglSwapBuffers(egl->display, egl->surface);
next_bo = gbm_surface_lock_front_buffer(gbm->surface);
+ struct drm_fb* fb = gbm_bo_get_user_data(next_bo);
+ if(fb)
+ printf("FB_ID: %d\n", fb->fb_id);
} else {
glFinish();
next_bo = gbm->bos[frame % NUM_BUFFERS];
With this the output on the console looks like this:
[...]
FB_ID: 111
FB_ID: 106
FB_ID: 106
FB_ID: 111
FB_ID: 106
FB_ID: 106
FB_ID: 111
FB_ID: 106
FB_ID: 106
FB_ID: 111
FB_ID: 106
FB_ID: 106
FB_ID: 111
FB_ID: 106
FB_ID: 106
[...]
When starting ksmcube with mesa_glthread=false
the output looks as expected:
[...]
FB_ID: 114
FB_ID: 108
FB_ID: 114
FB_ID: 108
FB_ID: 114
FB_ID: 108
FB_ID: 114
FB_ID: 108
FB_ID: 114
FB_ID: 108
FB_ID: 114
FB_ID: 108
FB_ID: 114
FB_ID: 108
FB_ID: 114
[...]
Regression
The issue doesn't occur with mesa_glthread=false
Screenshots/video files (if applicable)
Any extra information would be greatly appreciated
The problem in Kodi is worse when using OpenGL ES. With OpenGL ES the corruption is visible immediately after start. With OpenGL it works in the beginning but when starting a video, or after exiting a video, the issues begin. See also https://github.com/xbmc/xbmc/issues/23575 and https://github.com/xbmc/xbmc/pull/23793#issuecomment-1732724091.