[RFC xserver 15/16] modesetting: Create scanout buffers using supported modifiers

Daniel Stone daniels at collabora.com
Thu Jun 8 18:43:41 UTC 2017


From: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 glamor/glamor.h                                  |   7 ++
 glamor/glamor_egl.c                              |   2 +-
 hw/xfree86/drivers/modesetting/drmmode_display.c | 115 ++++++++++++++++++++---
 3 files changed, 109 insertions(+), 15 deletions(-)

diff --git a/glamor/glamor.h b/glamor/glamor.h
index d57d25046..e2b33ea12 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -332,6 +332,13 @@ extern _X_EXPORT Bool
  glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
                                                struct gbm_bo *bo);
 
+extern _X_EXPORT Bool
+glamor_egl_create_textured_pixmap_from_dmabuf(PixmapPtr pixmap,
+                                              CARD8 num_fds, int *fds,
+                                              CARD16 width, CARD16 height,
+                                              CARD32 *strides, CARD32 *offsets,
+                                              CARD32 format, uint64_t modifier);
+
 #endif
 
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 68bc8b0bd..99389ed49 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -236,7 +236,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
     return ret;
 }
 
-static Bool
+Bool
 glamor_egl_create_textured_pixmap_from_dmabuf(PixmapPtr pixmap,
                                               CARD8 num_fds, int *fds,
                                               CARD16 width, CARD16 height,
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 18a515d76..be3a90fbc 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -39,6 +39,7 @@
 #include "micmap.h"
 #include "xf86cmap.h"
 #include "xf86DDC.h"
+#include <drm_fourcc.h>
 
 #include <xf86drm.h>
 #include "xf86Crtc.h"
@@ -117,6 +118,45 @@ modifiers_ptr(struct drm_format_modifier_blob *blob)
     return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
 }
 
+static uint32_t
+get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **modifiers)
+{
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int c, i, j, k, count_modifiers = 0;
+
+    *modifiers = NULL;
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+        xf86CrtcPtr crtc = xf86_config->crtc[c];
+        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+        for (i = 0; i < drmmode_crtc->count_formats; i++) {
+            drmmode_format_ptr iter = &drmmode_crtc->formats[i];
+
+            if (iter->format != format)
+                continue;
+
+            for (j = 0; j < iter->count_modifiers; j++) {
+                Bool found = FALSE;
+
+                for (k = 0; k < count_modifiers; k++) {
+                    if (iter->modifiers[j] == (*modifiers)[k])
+                        found = TRUE;
+                }
+                if (!found) {
+                    count_modifiers++;
+                    *modifiers = realloc(*modifiers, count_modifiers * sizeof(uint64_t));
+                    if (!*modifiers) {
+                        return 0;
+                    }
+                    (*modifiers)[count_modifiers - 1] = iter->modifiers[j];
+                }
+            }
+        }
+    }
+
+    return count_modifiers;
+}
+
 static Bool
 drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name)
 {
@@ -554,6 +594,8 @@ drmmode_bo_get_pitch(drmmode_bo *bo)
 #ifdef GLAMOR_HAS_GBM
     if (bo->gbm)
         return gbm_bo_get_stride(bo->gbm);
+    if (bo->num_planes > 0)
+        return bo->strides[0];
 #endif
 
     return bo->dumb->pitch;
@@ -563,7 +605,7 @@ static Bool
 drmmode_bo_has_bo(drmmode_bo *bo)
 {
 #ifdef GLAMOR_HAS_GBM
-    if (bo->gbm)
+    if (bo->gbm || bo->num_planes > 0)
         return TRUE;
 #endif
 
@@ -587,7 +629,7 @@ drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo)
     int ret;
 
 #ifdef GLAMOR_HAS_GBM
-    if (bo->gbm)
+    if (bo->gbm || bo->num_planes > 0)
         return NULL;
 #endif
 
@@ -612,9 +654,11 @@ drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
 
         memset(handles, 0, sizeof(handles));
 
+        xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
+                   "Importing bo %p (nfds=%i, size=%ix%i)\n", bo, bo->num_planes, bo->width, bo->height);
         for (i = 0; i < bo->num_planes; i++) {
             ret = drmPrimeFDToHandle(drmmode->fd, bo->fds[i], &handles[i]);
-            if (ret != 0) //XXX close handles on error
+            if (ret != 0)
                 return ret;
         }
         ret = drmModeAddFB2WithModifiers(drmmode->fd, bo->width, bo->height,
@@ -622,13 +666,6 @@ drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
                                          bo->offsets, bo->modifiers, fb_id,
                                          DRM_MODE_FB_MODIFIERS);
 
-        for (i = 0; i < bo->num_planes; i++) {
-            struct drm_gem_close gem_close = { .handle = handles[i] };
-            if (!gem_close.handle)
-                continue;
-            (void) drmIoctl(drmmode->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
-        }
-
         return ret;
 #else
         xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
@@ -653,6 +690,45 @@ drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
 
 #ifdef GLAMOR_HAS_GBM
     if (drmmode->glamor) {
+#ifdef GBM_BO_WITH_MODIFIERS
+        // XXX if (glamor_egl->modifiers_capable) {
+            uint32_t num_modifiers;
+            uint64_t *modifiers = NULL;
+            struct gbm_bo *gbm;
+            int i;
+
+            /* The DRM module absolutely want us to initialize those to zero */
+            for (i = 0; i < 4; i++) {
+                bo->fds[i] = 0;
+                bo->strides[i] = 0;
+                bo->offsets[i] = 0;
+                bo->modifiers[i] = 0;
+            }
+
+            num_modifiers = get_modifiers_set(drmmode->scrn, DRM_FORMAT_ARGB8888,
+                                              &modifiers);
+            gbm = gbm_bo_create_with_modifiers(drmmode->gbm, width, height,
+                                               GBM_FORMAT_ARGB8888,
+                                               modifiers, num_modifiers);
+            free(modifiers);
+
+            if (!gbm)
+                return FALSE;
+
+            bo->num_planes = gbm_bo_get_plane_count(gbm);
+            bo->format = DRM_FORMAT_ARGB8888;
+            for (i = 0; i < bo->num_planes; i++) {
+                bo->fds[i] = gbm_bo_get_fd(gbm); // All planes use same handle
+                bo->strides[i] = gbm_bo_get_stride_for_plane(gbm, i);
+                bo->offsets[i] = gbm_bo_get_offset(gbm, i);
+                bo->modifiers[i] = gbm_bo_get_modifier(gbm);
+            }
+
+            gbm_bo_destroy(gbm);
+
+            return TRUE;
+        //}
+#endif
         bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
                                 GBM_FORMAT_ARGB8888,
                                 GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
@@ -1456,7 +1532,7 @@ drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 
 #ifdef GLAMOR_HAS_GBM
     if (drmmode->gbm)
-        return drmmode_crtc->rotate_bo.gbm;
+        return drmmode_crtc->rotate_bo.gbm; // XXX
 #endif
     return drmmode_crtc->rotate_bo.dumb;
 }
@@ -2642,9 +2718,20 @@ drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
     if (!drmmode->glamor)
         return TRUE;
 
-    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
-        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
-        return FALSE;
+    if (bo->num_planes > 0) {
+        if (!glamor_egl_create_textured_pixmap_from_dmabuf(pixmap, bo->num_planes,
+                                                           bo->fds,
+                                                           bo->width, bo->height,
+                                                           bo->strides, bo->offsets,
+                                                           bo->format, bo->modifiers[0])) {
+            xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
+            return FALSE;
+        }
+    } else {
+        if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
+            xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
+            return FALSE;
+        }
     }
 #endif
 
-- 
2.13.0



More information about the xorg-devel mailing list