xserver/hw/xfree86/drivers/modesetting
Mario Kleiner 5ff3310b69 modesetting: Allow Present flips with mismatched stride on atomic drivers.
When using DRI3+Present with PRIME render offload, sometimes there is
a mismatch between the stride of the to-be-presented Pixmap and the
frontbuffer. The current code would reject a pageflip present in this
case if atomic modesetting is not enabled, ie. always, as atomic
modesetting is disabled by default due to brokeness in the current
modesetting-ddx.

Fullscreen presents without page flipping however trigger the copy
path as fallback, which causes not only unreliable presentation timing
and degraded performance, but also massive tearing artifacts due to
rendering to the framebuffer without any hardware sync to vblank.
Tearing is extra awful on modesetting-ddx because glamor afaics seems
to use drawing of a textured triangle strip for the copy implementation,
not a dedicated blitter engine. The rasterization pattern creates extra
awful tearing artifacts.

We can do better: According to a tip from Michel Daenzer (thanks!),
at least atomic modesetting capable kms drivers should be able to
reliably change scanout stride during a pageflip, even if atomic
modesetting is not actually enabled for the modesetting client.

This commit adds detection logic to find out if the underlying kms
driver is atomic_modeset_capable, and if so, it no longer rejects
page flip presents on mismatched stride between new Pixmap and
frontbuffer.

We (ab)use a call to drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 0);
for this purpose. The call itself has no practical effect, as it
requests disabling atomic mode, although atomic mode is disabled by
default. However, the return value of drmSetClientCap() tells us if the
underlying kms driver is atomic modesetting capable: An atomic driver
will return 0 for success. A legacy non-atomic driver will return a
non-zero error code, either -EINVAL for early atomic Linux versions
4.0 - 4.19 (or for non-atomic Linux 3.x and earlier), or -EOPNOTSUPP
for Linux 4.20 and later.

Testing on a MacBookPro 2017 with Intel Kabylake display server gpu +
AMD Polaris11 as prime renderoffload gpu, X-Server master + Mesa 21.0.3
show improvement from unbearable tearing to perfect, despite a stride
mismatch between display gpu and Pixmap of 11776 Bytes vs. 11520
Bytes. That this is correct behaviour was also confirmed by comparing the
behaviour and .check_flip implementation of the patched modesetting-ddx
against the current intel-ddx SNA Present implementation.

Please consider merging this patch before the server-1.21 branch point.
This patch could also be cherry-picked into the server 1.20 branch to
fix the same limitation.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
(cherry picked from commit 8f8ebf870b)
2021-10-26 21:40:45 +02:00
..
Makefile.am modesetting: Fix broken manpage in autoconf build 2019-10-30 19:38:30 +00:00
dri2.c modesetting: Remove few common functions from ms namespace 2021-06-14 12:16:51 +02:00
driver.c modesetting: Allow Present flips with mismatched stride on atomic drivers. 2021-10-26 21:40:45 +02:00
driver.h modesetting: Allow Present flips with mismatched stride on atomic drivers. 2021-10-26 21:40:45 +02:00
drmmode_display.c modesetting: Fix possible_crtcs 2021-06-14 22:39:39 +00:00
drmmode_display.h modesetting: keep going if a modeset fails on EnterVT 2020-12-01 11:13:51 +01:00
dumb_bo.c modesetting: Include dix-config.h from dumb_bo.c 2015-05-12 08:02:11 -07:00
dumb_bo.h modesetting: Drop dumb_bo::map_count field and dead unmap code. 2014-12-11 11:26:19 -08:00
meson.build modesetting: set gbm as dependency in meson build 2018-05-08 12:41:58 -04:00
modesetting.man modesetting: Document Option "DoubleShadow" in the man page 2018-10-04 17:25:52 +02:00
pageflip.c modesetting: Remove few common functions from ms namespace 2021-06-14 12:16:51 +02:00
present.c modesetting: Allow Present flips with mismatched stride on atomic drivers. 2021-10-26 21:40:45 +02:00
vblank.c modesetting: Remove few common functions from ms namespace 2021-06-14 12:16:51 +02:00