summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.c46
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.h4
-rw-r--r--hw/xfree86/drivers/modesetting/pageflip.c16
3 files changed, 59 insertions, 7 deletions
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 4fed593ba..536274f3f 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -39,6 +39,8 @@
#include "micmap.h"
#include "xf86cmap.h"
#include "xf86DDC.h"
+#include <drm_fourcc.h>
+#include <drm_mode.h>
#include <xf86drm.h>
#include "xf86Crtc.h"
@@ -388,10 +390,54 @@ drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo)
return bo->dumb->ptr;
}
+int
+drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
+ uint32_t *fb_id)
+{
+#ifdef GBM_BO_WITH_MODIFIERS
+ if (bo->gbm) {
+ int num_fds;
+
+ num_fds = gbm_bo_get_plane_count(bo->gbm);
+ if (num_fds > 0) {
+ int i;
+ uint32_t handles[4];
+ uint32_t strides[4];
+ uint32_t offsets[4];
+ uint64_t modifiers[4];
+
+ memset(handles, 0, sizeof(handles));
+ memset(strides, 0, sizeof(strides));
+ memset(offsets, 0, sizeof(offsets));
+ memset(modifiers, 0, sizeof(modifiers));
+
+ for (i = 0; i < num_fds; i++) {
+ handles[i] = gbm_bo_get_handle_for_plane(bo->gbm, i).u32;
+ strides[i] = gbm_bo_get_stride_for_plane(bo->gbm, i);
+ offsets[i] = gbm_bo_get_offset(bo->gbm, i);
+ modifiers[i] = gbm_bo_get_modifier(bo->gbm);
+ }
+
+ return drmModeAddFB2WithModifiers(drmmode->fd, bo->width, bo->height,
+ DRM_FORMAT_ARGB8888, handles, strides,
+ offsets, modifiers, fb_id,
+ DRM_MODE_FB_MODIFIERS);
+ }
+ }
+#endif
+ return drmModeAddFB(drmmode->fd, bo->width, bo->height,
+ drmmode->scrn->depth, drmmode->scrn->bitsPerPixel,
+ drmmode_bo_get_pitch(bo),
+ drmmode_bo_get_handle(bo), fb_id);
+}
+
static Bool
drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
unsigned width, unsigned height, unsigned bpp)
{
+ bo->width = width;
+ bo->height = height;
+
#ifdef GLAMOR_HAS_GBM
if (drmmode->glamor) {
bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index fadc381db..0a4452e7b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -51,6 +51,8 @@ enum drmmode_plane_type {
};
typedef struct {
+ uint32_t width;
+ uint32_t height;
struct dumb_bo *dumb;
#ifdef GLAMOR_HAS_GBM
struct gbm_bo *gbm;
@@ -193,6 +195,8 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
#define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
+int drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
+ uint32_t *fb_id);
int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo);
uint32_t drmmode_bo_get_pitch(drmmode_bo *bo);
uint32_t drmmode_bo_get_handle(drmmode_bo *bo);
diff --git a/hw/xfree86/drivers/modesetting/pageflip.c b/hw/xfree86/drivers/modesetting/pageflip.c
index dd296cd12..027ebfe42 100644
--- a/hw/xfree86/drivers/modesetting/pageflip.c
+++ b/hw/xfree86/drivers/modesetting/pageflip.c
@@ -258,6 +258,7 @@ ms_do_pageflip(ScreenPtr screen,
new_front_bo.gbm = glamor_gbm_bo_from_pixmap(screen, new_front);
new_front_bo.dumb = NULL;
+
if (!new_front_bo.gbm) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to get GBM bo for flip to new front.\n");
@@ -288,14 +289,12 @@ ms_do_pageflip(ScreenPtr screen,
/* Create a new handle for the back buffer */
flipdata->old_fb_id = ms->drmmode.fb_id;
- if (drmModeAddFB(ms->fd, scrn->virtualX, scrn->virtualY,
- scrn->depth, scrn->bitsPerPixel,
- drmmode_bo_get_pitch(&new_front_bo),
- drmmode_bo_get_handle(&new_front_bo), &ms->drmmode.fb_id)) {
- goto error_out;
- }
- drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
+ new_front_bo.width = new_front->drawable.width;
+ new_front_bo.height = new_front->drawable.height;
+ if (drmmode_bo_import(&ms->drmmode, &new_front_bo,
+ &ms->drmmode.fb_id))
+ goto error_out;
flags = DRM_MODE_PAGE_FLIP_EVENT;
if (async)
@@ -323,6 +322,8 @@ ms_do_pageflip(ScreenPtr screen,
}
}
+ drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
+
/*
* Do we have more than our local reference,
* if so and no errors, then drop our local
@@ -348,6 +349,7 @@ error_undo:
error_out:
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
strerror(errno));
+ drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
/* if only the local reference - free the structure,
* else drop the local reference and return */
if (flipdata->flip_count == 1)