xserver: Branch 'master'

Adam Jackson ajax at kemper.freedesktop.org
Mon Apr 23 18:08:17 UTC 2018


 hw/xfree86/drivers/modesetting/driver.c          |    5 +++++
 hw/xfree86/drivers/modesetting/driver.h          |    2 ++
 hw/xfree86/drivers/modesetting/drmmode_display.c |   13 ++++++-------
 3 files changed, 13 insertions(+), 7 deletions(-)

New commits:
commit e29d783278608544a208f211231a6a3ad2f8fa09
Author: Mario Kleiner <mario.kleiner.de at gmail.com>
Date:   Fri Apr 20 19:59:40 2018 +0200

    modesetting: Only use modifiers on kms drivers which do support them.
    
    Use the DRM_CAP_ADDFB2_MODIFIERS query to make sure the kms
    driver supports modifiers in the addfb2 ioctl, and fall back
    to addfb ioctl without modifiers if modifiers are unsupported.
    
    E.g., as of Linux 4.17, nouveau-kms so far does not suppport
    modifiers and gets angry if drmModeAddFB2WithModifiers() is
    called (-> failure to set a video mode -> blank screen), but
    Mesa's nvc0+ gallium driver causes gbm_bo_get_modifier() to
    return a valid modifier by translating the default tiling of
    bo's created via gbm_bo_create() into a modifier other than
    DRM_FORMAT_MOD_INVALID (see Mesa's nvc0_miptree_get_modifier()).
    
    Testing for != DRM_FORMAT_MOD_INVALID is apparently not
    sufficient for safe use of drmModeAddFB2WithModifiers.
    
    Bonus: Handle potential failure of populate_format_modifiers().
    
    The required DRM_CAP is defined since libdrm v2.4.65, and we
    require v2.4.89+ for the server, so we can use it unconditionally.
    
    Tested on intel-kms, radeon-kms, nouveau-kms. Fixes failure on
    NVidia Pascal.
    
    Fixes: 2f807c2324b4 ("modesetting: Add support for multi-plane pixmaps when page-flipping")
    Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
    Cc: Daniel Stone <daniels at collabora.com>
    Cc: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
    Reviewed-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 7682b24f1..5d8906d63 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1018,6 +1018,11 @@ PreInit(ScrnInfoPtr pScrn, int flags)
     ret |= drmSetClientCap(ms->fd, DRM_CLIENT_CAP_ATOMIC, 1);
     ms->atomic_modeset = (ret == 0);
 
+    ms->kms_has_modifiers = FALSE;
+    ret = drmGetCap(ms->fd, DRM_CAP_ADDFB2_MODIFIERS, &value);
+    if (ret == 0 && value != 0)
+        ms->kms_has_modifiers = TRUE;
+
     if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n");
         goto fail;
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index cb8cfe634..b2a4e52f8 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -117,6 +117,8 @@ typedef struct _modesettingRec {
     Bool has_queue_sequence;
     Bool tried_queue_sequence;
 
+    Bool kms_has_modifiers;
+
 } modesettingRec, *modesettingPtr;
 
 #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 79e91f0f8..859a21a9d 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -954,7 +954,8 @@ drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
                   uint32_t *fb_id)
 {
 #ifdef GBM_BO_WITH_MODIFIERS
-    if (bo->gbm &&
+    modesettingPtr ms = modesettingPTR(drmmode->scrn);
+    if (bo->gbm && ms->kms_has_modifiers &&
         gbm_bo_get_modifier(bo->gbm) != DRM_FORMAT_MOD_INVALID) {
         int num_fds;
 
@@ -1974,6 +1975,9 @@ populate_format_modifiers(xf86CrtcPtr crtc, const drmModePlane *kplane,
     uint32_t *blob_formats;
     struct drm_format_modifier *blob_modifiers;
 
+    if (!blob_id)
+        return FALSE;
+
     blob = drmModeGetPropertyBlob(drmmode->fd, blob_id);
     if (!blob)
         return FALSE;
@@ -1988,7 +1992,6 @@ populate_format_modifiers(xf86CrtcPtr crtc, const drmModePlane *kplane,
         uint32_t num_modifiers = 0;
         uint64_t *modifiers = NULL;
         uint64_t *tmp;
-
         for (j = 0; j < fmt_mod_blob->count_modifiers; j++) {
             struct drm_format_modifier *mod = &blob_modifiers[j];
 
@@ -2147,11 +2150,7 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
         drmmode_crtc->num_formats = best_kplane->count_formats;
         drmmode_crtc->formats = calloc(sizeof(drmmode_format_rec),
                                        best_kplane->count_formats);
-        if (blob_id) {
-            populate_format_modifiers(crtc, best_kplane, blob_id);
-        }
-        else
-        {
+        if (!populate_format_modifiers(crtc, best_kplane, blob_id)) {
             for (i = 0; i < best_kplane->count_formats; i++)
                 drmmode_crtc->formats[i].format = best_kplane->formats[i];
         }


More information about the xorg-commit mailing list