[PATCH v2 xserver 07/11] modesetting: separate render and display
Qiang Yu
Qiang.Yu at amd.com
Sat Jan 7 08:01:28 UTC 2017
Signed-off-by: Qiang Yu <Qiang.Yu at amd.com>
---
hw/xfree86/drivers/modesetting/dri2.c | 8 +++-
hw/xfree86/drivers/modesetting/driver.c | 26 ++++++++---
hw/xfree86/drivers/modesetting/drmmode_display.c | 57 ++++++++++++++++++++++--
hw/xfree86/drivers/modesetting/drmmode_display.h | 2 +
hw/xfree86/drivers/modesetting/present.c | 4 ++
5 files changed, 86 insertions(+), 11 deletions(-)
diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 8944ef1..a01ef27 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -536,6 +536,7 @@ can_exchange(ScrnInfoPtr scrn, DrawablePtr draw,
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int num_crtcs_on = 0;
int i;
+ modesettingPtr ms = modesettingPTR(scrn);
for (i = 0; i < config->num_crtc; i++) {
drmmode_crtc_private_ptr drmmode_crtc = config->crtc[i]->driver_private;
@@ -572,6 +573,9 @@ can_exchange(ScrnInfoPtr scrn, DrawablePtr draw,
if (front_pixmap->devKind != back_pixmap->devKind)
return FALSE;
+ if (ms->rfd >= 0)
+ return FALSE;
+
return TRUE;
}
@@ -1085,9 +1089,9 @@ ms_dri2_screen_init(ScreenPtr screen)
}
memset(&info, '\0', sizeof(info));
- info.fd = ms->fd;
+ info.fd = ms->rfd < 0 ? ms->fd : ms->rfd;
info.driverName = NULL; /* Compat field, unused. */
- info.deviceName = drmGetDeviceNameFromFd(ms->fd);
+ info.deviceName = drmGetDeviceNameFromFd(ms->rfd < 0 ? ms->fd : ms->rfd);
info.version = 9;
info.CreateBuffer = ms_dri2_create_buffer;
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 321fedc..782159a 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -739,10 +739,16 @@ FreeRec(ScrnInfoPtr pScrn)
if (!ms)
return;
+ if (ms->rfd >= 0) {
+#ifdef GLAMOR_HAS_GBM
+ if (ms->drmmode.gbm)
+ gbm_device_destroy(ms->drmmode.gbm);
+#endif
+ ms_free_ent(ms->prEnt);
+ }
+
if (ms->fd >= 0)
ms_free_ent(ms->pEnt);
- if (ms->rfd >= 0)
- ms_free_ent(ms->prEnt);
pScrn->driverPrivate = NULL;
free(ms->drmmode.Options);
@@ -772,7 +778,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
}
if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) {
- if (glamor_egl_init(pScrn, ms->fd)) {
+ if (glamor_egl_init(pScrn, ms->rfd < 0 ? ms->fd : ms->rfd)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n");
ms->drmmode.glamor = TRUE;
} else {
@@ -1620,8 +1626,18 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
return FALSE;
#ifdef GLAMOR_HAS_GBM
- if (ms->drmmode.glamor)
- ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
+ if (ms->drmmode.glamor) {
+ if (ms->rfd < 0) {
+ ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
+ ms->drmmode.rgbm = NULL;
+ }
+ else {
+ ms->drmmode.gbm = gbm_create_device(ms->fd);
+ if (!ms->drmmode.gbm)
+ return FALSE;
+ ms->drmmode.rgbm = glamor_egl_get_gbm_device(pScreen);
+ }
+ }
#endif
/* HW dependent - FIXME */
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 4bfaace..4ed5f6b 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -97,6 +97,10 @@ drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
gbm_bo_destroy(bo->gbm);
bo->gbm = NULL;
}
+ if (bo->rgbm) {
+ gbm_bo_destroy(bo->rgbm);
+ bo->rgbm = NULL;
+ }
#endif
if (bo->dumb) {
@@ -167,9 +171,29 @@ drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
{
#ifdef GLAMOR_HAS_GBM
if (drmmode->glamor) {
+ int usage = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT;
+ if (drmmode->rgbm)
+ usage |= GBM_BO_USE_LINEAR;
bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
- GBM_FORMAT_ARGB8888,
- GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+ GBM_FORMAT_ARGB8888, usage);
+ bo->rgbm = NULL;
+ if (drmmode->rgbm && bo->gbm) {
+ int fd = gbm_bo_get_fd(bo->gbm);
+ if (fd >= 0) {
+ struct gbm_import_fd_data import_data = { 0 };
+ import_data.fd = fd;
+ import_data.width = gbm_bo_get_width(bo->gbm);
+ import_data.height = gbm_bo_get_height(bo->gbm);
+ import_data.stride = gbm_bo_get_stride(bo->gbm);
+ import_data.format = gbm_bo_get_format(bo->gbm);
+ bo->rgbm = gbm_bo_import(drmmode->rgbm, GBM_BO_IMPORT_FD, &import_data, 0);
+ close(fd);
+ }
+ if (!bo->rgbm) {
+ gbm_bo_destroy(bo->gbm);
+ bo->gbm = NULL;
+ }
+ }
return bo->gbm != NULL;
}
#endif
@@ -189,7 +213,32 @@ drmmode_bo_for_pixmap(drmmode_ptr drmmode, drmmode_bo *bo, PixmapPtr pixmap)
#ifdef GLAMOR_HAS_GBM
if (drmmode->glamor) {
- bo->gbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
+ struct gbm_bo *gbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
+ if (!gbm)
+ bo->gbm = bo->rgbm = NULL;
+ else if (!drmmode->rgbm) {
+ bo->gbm = gbm;
+ bo->rgbm = NULL;
+ }
+ else {
+ bo->rgbm = gbm;
+ bo->gbm = NULL;
+ fd = gbm_bo_get_fd(bo->rgbm);
+ if (fd >= 0) {
+ struct gbm_import_fd_data import_data = { 0 };
+ import_data.fd = fd;
+ import_data.width = gbm_bo_get_width(bo->rgbm);
+ import_data.height = gbm_bo_get_height(bo->rgbm);
+ import_data.stride = gbm_bo_get_stride(bo->rgbm);
+ import_data.format = gbm_bo_get_format(bo->rgbm);
+ bo->gbm = gbm_bo_import(drmmode->gbm, GBM_BO_IMPORT_FD, &import_data, 0);
+ close(fd);
+ }
+ if (!bo->gbm) {
+ gbm_bo_destroy(bo->rgbm);
+ bo->rgbm = NULL;
+ }
+ }
bo->dumb = NULL;
return bo->gbm != NULL;
}
@@ -1940,7 +1989,7 @@ drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
return TRUE;
#ifdef GLAMOR_HAS_GBM
- if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
+ if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->rgbm ? bo->rgbm : bo->gbm)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
return FALSE;
}
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index da7d5d7..5ab7f34 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -40,6 +40,7 @@ typedef struct {
struct dumb_bo *dumb;
#ifdef GLAMOR_HAS_GBM
struct gbm_bo *gbm;
+ struct gbm_bo *rgbm;
#endif
} drmmode_bo;
@@ -52,6 +53,7 @@ typedef struct {
ScrnInfoPtr scrn;
struct gbm_device *gbm;
+ struct gbm_device *rgbm;
#ifdef CONFIG_UDEV_KMS
struct udev_monitor *uevent_monitor;
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 55b622c..83add7d 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -272,6 +272,10 @@ ms_present_check_flip(RRCrtcPtr crtc,
if (pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
return FALSE;
+ /* can't flip to a user created bo with tile */
+ if (ms->rfd >= 0)
+ return FALSE;
+
/* Make sure there's a bo we can get to */
/* XXX: actually do this. also...is it sufficient?
* if (!glamor_get_pixmap_private(pixmap))
--
2.7.4
More information about the xorg-devel
mailing list