xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Sep 7 09:29:29 UTC 2021


 hw/xfree86/drivers/modesetting/driver.c  |    8 ++++++++
 hw/xfree86/drivers/modesetting/driver.h  |    1 +
 hw/xfree86/drivers/modesetting/present.c |    7 +++++--
 3 files changed, 14 insertions(+), 2 deletions(-)

New commits:
commit 8f8ebf870b55c9875b7cfd8ef69c1df02d589b4a
Author: Mario Kleiner <mario.kleiner.de at gmail.com>
Date:   Sat Aug 28 02:27:20 2021 +0200

    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 at gmail.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index df1abea17..fde65e0e5 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1220,6 +1220,14 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 #endif
     }
 
+    /*
+     * Use "atomic modesetting disable" request to detect if the kms driver is
+     * atomic capable, regardless if we will actually use atomic modesetting.
+     * This is effectively a no-op, we only care about the return status code.
+     */
+    ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 0);
+    ms->atomic_modeset_capable = (ret == 0);
+
     if (xf86ReturnOptValBool(ms->drmmode.Options, OPTION_ATOMIC, FALSE)) {
         ret = drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1);
         ms->atomic_modeset = (ret == 0);
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 114971048..6217a0e64 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -116,6 +116,7 @@ typedef struct _modesettingRec {
      * Page flipping stuff.
      *  @{
      */
+    Bool atomic_modeset_capable;
     Bool atomic_modeset;
     Bool pending_modeset;
     /** @} */
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 916a15303..b90a1b8ac 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -267,8 +267,11 @@ ms_present_check_unflip(RRCrtcPtr crtc,
     if (num_crtcs_on == 0)
         return FALSE;
 
-    /* Check stride, can't change that on flip */
-    if (!ms->atomic_modeset &&
+    /*
+     * Check stride, can't change that reliably on flip on some drivers, unless
+     * the kms driver is atomic_modeset_capable.
+     */
+    if (!ms->atomic_modeset_capable &&
         pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
         return FALSE;
 


More information about the xorg-commit mailing list