[RFC v2 13/13] modesetting: Create scanout buffers using supported modifiers
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Fri Jul 14 04:48:00 UTC 2017
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
glamor/glamor.h | 7 ++
glamor/glamor_egl.c | 2 +-
hw/xfree86/drivers/modesetting/drmmode_display.c | 111 ++++++++++++++++++++---
3 files changed, 106 insertions(+), 14 deletions(-)
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 044480597..19606ca5f 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -391,6 +391,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 af956a05d..f57e59026 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 17fbd814e..27e90c02e 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 <drm_mode.h>
#include <xf86drm.h>
@@ -72,6 +73,48 @@ modifiers_ptr(struct drm_format_modifier_blob *blob)
#endif
+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;
+ uint64_t *tmp, *ret = NULL;
+
+ *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] == ret[k])
+ found = TRUE;
+ }
+ if (!found) {
+ count_modifiers++;
+ tmp = realloc(ret, count_modifiers * sizeof(uint64_t));
+ if (!tmp) {
+ free(ret);
+ return 0;
+ }
+ ret[count_modifiers - 1] = iter->modifiers[j];
+ }
+ }
+ }
+ }
+
+ *modifiers = ret;
+ return count_modifiers;
+}
+
static Bool
drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name)
{
@@ -506,6 +549,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;
@@ -515,7 +560,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
@@ -539,7 +584,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
@@ -566,7 +611,7 @@ drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
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,
@@ -574,13 +619,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,
@@ -605,6 +643,42 @@ drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
#ifdef GLAMOR_HAS_GBM
if (drmmode->glamor) {
+#ifdef GBM_BO_WITH_MODIFIERS
+ uint32_t num_modifiers;
+ uint64_t *modifiers = NULL;
+ struct gbm_bo *gbm = NULL;
+ 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);
+
+ /* Fallback to gbm_bo_create below if it fails */
+ if (gbm) {
+ 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);
@@ -2605,9 +2679,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