[PATCH xf86-video-dummy] Add glamor acceleration which enables native OpenGL support

Qiang Yu Qiang.Yu at amd.com
Tue Mar 7 03:53:57 UTC 2017


Enable glamor acceleration in xorg.conf by:
Section "Device"
  ...
  Driver "dummy"
  Option "Render" "/dev/dri/renderD128"
  ...
EndSection

GPU is chosen by the Render option which specifies the render
node of the GPU DRM device.

We could use the dumb buffer instead of gbm buffer as the
screen front buffer. But dumb buffer requires open
/dev/dri/cardx which has the limitation of only one instance
of OpenGL enabled xserver can start.

With gbm buffer, we can use /dev/dri/renderDx which has no
limitation on the number of OpenGL enabled xserver and even
won't conflict with a "real" xserver using radeon/amdgpu DDX.

Due to using renderDx, only DRI3 OpenGL is supported.

DGA is disabled when glamor is enabled, we can enable it with
new gbm_bo_map/unmap API, but consider a more effiction way
is just using DRI3BufferFromPixmap for the root window pixmap.

Signed-off-by: Qiang Yu <Qiang.Yu at amd.com>
---
 configure.ac       |  26 ++++++++++
 src/Makefile.am    |   7 ++-
 src/dummy.h        |   9 ++++
 src/dummy_dga.c    |   3 ++
 src/dummy_driver.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 176 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index 4eb7fae..7239b63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,6 +68,32 @@ AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
 # Obtain compiler/linker options for the driver dependencies
 PKG_CHECK_MODULES(XORG, [xorg-server >= 1.4.99.901] xproto fontsproto $REQUIRED_MODULES)
 
+# Check glamor support
+AC_ARG_ENABLE(glamor,
+	      AS_HELP_STRING([--disable-glamor],
+			     [Disable glamor, a new GL-based acceleration [default=enabled]]),
+	      [GLAMOR="$enableval"],
+	      [GLAMOR=yes])
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $XORG_CFLAGS"
+if test "x$GLAMOR" != "xno"; then
+	AC_CHECK_HEADERS([glamor.h], , [GLAMOR=no], [#include "xorg-server.h"])
+fi
+CPPFLAGS="$SAVE_CPPFLAGS"
+
+if test "x$GLAMOR" != "xno"; then
+	PKG_CHECK_MODULES(GBM, [gbm], , [GLAMOR=no])
+fi
+
+AC_MSG_CHECKING([whether to include GLAMOR support])
+AC_MSG_RESULT([$GLAMOR])
+
+if test "x$GLAMOR" != "xno"; then
+        AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration])
+fi
+AM_CONDITIONAL(GLAMOR, test x$GLAMOR != xno)
+
 # Checks for libraries.
 
 
diff --git a/src/Makefile.am b/src/Makefile.am
index da1dd9a..9faa9c4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,7 +25,7 @@
 # _ladir passes a dummy rpath to libtool so the thing will actually link
 # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
 
-AM_CFLAGS = $(XORG_CFLAGS) $(PCIACCESS_CFLAGS)
+AM_CFLAGS = $(XORG_CFLAGS)
 
 dummy_drv_la_LTLIBRARIES = dummy_drv.la
 dummy_drv_la_LDFLAGS = -module -avoid-version
@@ -38,6 +38,11 @@ dummy_drv_la_SOURCES = \
          dummy_driver.c \
          dummy.h
 
+if GLAMOR
+AM_CFLAGS += $(GBM_CFLAGS)
+dummy_drv_la_LIBADD += $(GBM_LIBS)
+endif
+
 if DGA
 dummy_drv_la_SOURCES +=	\
          dummy_dga.c
diff --git a/src/dummy.h b/src/dummy.h
index c3fdd6e..1eecdec 100644
--- a/src/dummy.h
+++ b/src/dummy.h
@@ -42,6 +42,9 @@ typedef struct _color
     int blue;
 } dummy_colors;
 
+struct gbm_device;
+struct gbm_bo;
+
 typedef struct dummyRec 
 {
     DGAModePtr		DGAModes;
@@ -72,6 +75,12 @@ typedef struct dummyRec
     pointer* FBBase;
     Bool        (*CreateWindow)() ;     /* wrapped CreateWindow */
     Bool prop;
+
+    /* DRI support */
+    int fd;
+    CreateScreenResourcesProcPtr createScreenResources;
+    struct gbm_device *gbm;
+    struct gbm_bo *front_bo;
 } DUMMYRec, *DUMMYPtr;
 
 /* The privates of the DUMMY driver */
diff --git a/src/dummy_dga.c b/src/dummy_dga.c
index d16d09f..8335874 100644
--- a/src/dummy_dga.c
+++ b/src/dummy_dga.c
@@ -165,6 +165,9 @@ DUMMY_OpenFramebuffer(
 ){
     DUMMYPtr pDUMMY = DUMMYPTR(pScrn);
 
+    if (pDUMMY->FBBase == NULL)
+	return FALSE;
+
     *name = NULL; 		/* no special device */
     *mem = (unsigned char*)pDUMMY->FBBase;
     *size = pScrn->videoRam * 1024;
diff --git a/src/dummy_driver.c b/src/dummy_driver.c
index 2656602..174695c 100644
--- a/src/dummy_driver.c
+++ b/src/dummy_driver.c
@@ -49,6 +49,15 @@
 #include <X11/extensions/xf86dgaproto.h>
 #endif
 
+#ifdef USE_GLAMOR
+#define GLAMOR_FOR_XORG
+#include <glamor.h>
+#include <gbm.h>
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+
 /* Mandatory functions */
 static const OptionInfoRec *	DUMMYAvailableOptions(int chipid, int busid);
 static void     DUMMYIdentify(int flags);
@@ -115,11 +124,13 @@ static SymTabRec DUMMYChipsets[] = {
 };
 
 typedef enum {
-    OPTION_SW_CURSOR
+    OPTION_SW_CURSOR,
+    OPTION_RENDER,
 } DUMMYOpts;
 
 static const OptionInfoRec DUMMYOptions[] = {
     { OPTION_SW_CURSOR,	"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
+    { OPTION_RENDER,	"Render",	OPTV_STRING,	{0}, FALSE },
     { -1,                  NULL,           OPTV_NONE,	{0}, FALSE }
 };
 
@@ -189,15 +200,21 @@ DUMMYGetRec(ScrnInfoPtr pScrn)
 
     if (pScrn->driverPrivate == NULL)
 	return FALSE;
-        return TRUE;
+    return TRUE;
 }
 
 static void
 DUMMYFreeRec(ScrnInfoPtr pScrn)
 {
-    if (pScrn->driverPrivate == NULL)
+    DUMMYPtr dPtr = DUMMYPTR(pScrn);
+
+    if (!dPtr)
 	return;
-    free(pScrn->driverPrivate);
+
+    if (dPtr->fd >= 0)
+	close(dPtr->fd);
+
+    free(dPtr);
     pScrn->driverPrivate = NULL;
 }
 
@@ -266,10 +283,50 @@ DUMMYProbe(DriverPtr drv, int flags)
     return foundScreen;
 }
 
+static void
+try_enable_glamor(ScrnInfoPtr pScrn)
+{
+#ifdef USE_GLAMOR
+    Bool enabled = FALSE;
+    const char *render;
+    DUMMYPtr dPtr = DUMMYPTR(pScrn);
+    uint64_t value = 0;
+    int ret;
+
+    render = xf86GetOptValString(dPtr->Options, OPTION_RENDER);
+    if (!render)
+	return;
+
+    dPtr->fd = open(render, O_RDWR);
+    if (dPtr->fd < 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Open render %s fail\n", render);
+	return;
+    }
+
+    if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) {
+        if (glamor_egl_init(pScrn, dPtr->fd)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n");
+	    enabled = TRUE;
+	} else {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "glamor initialization failed\n");
+	}
+    } else {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Failed to load glamor module.\n");
+    }
+
+    if (!enabled) {
+	close(dPtr->fd);
+	dPtr->fd = -1;
+    }
+#endif
+}
+
 # define RETURN \
     { DUMMYFreeRec(pScrn);\
-			    return FALSE;\
-					     }
+	return FALSE;\
+    }
 
 /* Mandatory */
 Bool
@@ -290,6 +347,7 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags)
     }
     
     dPtr = DUMMYPTR(pScrn);
+    dPtr->fd = -1;
 
     pScrn->chipset = (char *)xf86TokenToString(DUMMYChipsets,
 					       DUMMY_CHIP);
@@ -450,6 +508,8 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags)
     pScrn->memPhysBase = 0;
     pScrn->fbOffset = 0;
 
+    try_enable_glamor(pScrn);
+
     return TRUE;
 }
 #undef RETURN
@@ -500,6 +560,31 @@ DUMMYLoadPalette(
 
 }
 
+#ifdef USE_GLAMOR
+static Bool
+DUMMYCreateScreenResources(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    DUMMYPtr dPtr = DUMMYPTR(pScrn);
+    PixmapPtr pixmap;
+    Bool ret;
+    void *pixels = NULL;
+
+    pScreen->CreateScreenResources = dPtr->createScreenResources;
+    ret = pScreen->CreateScreenResources(pScreen);
+    pScreen->CreateScreenResources = DUMMYCreateScreenResources;
+
+    pixmap = pScreen->GetScreenPixmap(pScreen);
+    if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, dPtr->front_bo)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "glamor_egl_create_textured_pixmap() failed\n");
+	return FALSE;
+    }
+
+    glamor_set_screen_pixmap(pixmap, NULL);
+}
+#endif
+
 static ScrnInfoPtr DUMMYScrn; /* static-globalize it */
 
 /* Mandatory */
@@ -519,8 +604,7 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
     dPtr = DUMMYPTR(pScrn);
     DUMMYScrn = pScrn;
 
-
-    if (!(dPtr->FBBase = malloc(pScrn->videoRam * 1024)))
+    if (dPtr->fd < 0 && !(dPtr->FBBase = malloc(pScrn->videoRam * 1024)))
 	return FALSE;
 
     /*
@@ -566,6 +650,35 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
     /* must be after RGB ordering fixed */
     fbPictureInit(pScreen, 0, 0);
 
+#ifdef USE_GLAMOR
+    if (dPtr->fd >= 0) {
+	dPtr->gbm = glamor_egl_get_gbm_device(pScreen);
+	if (!dPtr->gbm) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Failed to get gbm device.\n");
+	    return FALSE;
+	}
+	dPtr->front_bo = gbm_bo_create(dPtr->gbm,
+				       pScrn->virtualX, pScrn->virtualY,
+				       GBM_FORMAT_ARGB8888,
+				       GBM_BO_USE_RENDERING);
+	if (!dPtr->front_bo) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Failed to create front buffer.\n");
+	    return FALSE;
+	}
+
+        if (!glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Failed to initialize glamor at ScreenInit() time.\n");
+            return FALSE;
+        }
+
+	dPtr->createScreenResources = pScreen->CreateScreenResources;
+	pScreen->CreateScreenResources = DUMMYCreateScreenResources;
+    }
+#endif
+
     xf86SetBlackWhitePixels(pScreen);
 
 #ifdef USE_DGA
@@ -659,9 +772,17 @@ DUMMYCloseScreen(CLOSE_SCREEN_ARGS_DECL)
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     DUMMYPtr dPtr = DUMMYPTR(pScrn);
 
-    if(pScrn->vtSema){
-	free(dPtr->FBBase);
-    }
+#ifdef USE_GLAMOR
+    if (dPtr->fd >= 0) {
+	if (dPtr->front_bo) {
+	    gbm_bo_destroy(dPtr->front_bo);
+	    dPtr->front_bo = NULL;
+	}
+    } else
+#endif
+	if(pScrn->vtSema) {
+	    free(dPtr->FBBase);
+	}
 
     if (dPtr->CursorInfo)
 	xf86DestroyCursorInfoRec(dPtr->CursorInfo);
-- 
2.7.4



More information about the xorg-devel mailing list