[PATCH v2 xf86-video-dummy] Add glamor acceleration which enables native OpenGL support (v2)
Antoine Martin
antoine at nagafix.co.uk
Sat Aug 5 12:54:11 UTC 2017
On 09/03/17 09:26, Qiang Yu wrote:
> v2:
> Update configure.ac for auto enable glamor support and print
> corresponding error message when necessary.
>
> Enable glamor acceleration in xorg.conf by:
> Section "Device"
> ...
> Driver "dummy"
> Option "Render" "/dev/dri/renderD128"
> ...
> EndSection
With an nvidia driver, I get:
[119367.649] (II) Loading /usr/lib64/xorg/modules/libglamoregl.so
[119367.649] (II) Module glamoregl: vendor="X.Org Foundation"
[119367.649] compiled for 1.19.3, module version = 1.0.0
[119367.649] ABI class: X.Org ANSI C Emulation, version 0.4
[119367.649] (II) glamor: OpenGL accelerated X.org driver based.
[119367.654] (II) glamor: EGL version 1.4 (DRI2):
[119367.654] EGL_MESA_drm_image required.
[119367.654] (EE) DUMMY(0): glamor initialization failed
And with modesetting or intel drivers:
[ 738.822] (II) glamor: OpenGL accelerated X.org driver based.
[ 738.827] (II) glamor: EGL version 1.4 (DRI2):
[ 738.836] (II) DUMMY(0): glamor initialized
[ 738.836] (--) Depth 24 pixmap format is 32 bpp
[ 738.957] (II) DUMMY(0): Using 3904 scanlines of offscreen memory
[ 738.957] (==) DUMMY(0): Backing store enabled
[ 738.957] (==) DUMMY(0): Silken mouse enabled
[ 738.957] (==) RandR enabled
[ 738.959] (II) SELinux: Disabled by boolean
[ 738.960] (II) AIGLX: Screen 0 is not DRI2 capable
[ 738.960] (EE) AIGLX: reverting to software rendering
And in both cases, glxinfo reports that my dummy screen uses software
rendering. (Accelerated: no, Gallium 0.4 on llvmpipe..)
What am I doing wrong?
Cheers
Antoine
>
> 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 | 38 ++++++++++++++
> src/Makefile.am | 7 ++-
> src/dummy.h | 9 ++++
> src/dummy_dga.c | 3 ++
> src/dummy_driver.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++-----
> 5 files changed, 188 insertions(+), 12 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 4eb7fae..39d2157 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -68,6 +68,44 @@ 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=auto]]),
> + [GLAMOR="$enableval"],
> + [GLAMOR=auto])
> +
> +SAVE_CPPFLAGS="$CPPFLAGS"
> +CPPFLAGS="$CPPFLAGS $XORG_CFLAGS"
> +if test "x$GLAMOR" != "xno"; then
> + AC_CHECK_HEADERS([glamor.h], [HAS_GLAMOR=yes], [HAS_GLAMOR=no], [#include "xorg-server.h"])
> + PKG_CHECK_MODULES(GBM, [gbm], [], [HAS_GLAMOR=no])
> +fi
> +CPPFLAGS="$SAVE_CPPFLAGS"
> +
> +case "$GLAMOR,$HAS_GLAMOR" in
> + yes,yes | auto,yes)
> + GLAMOR=yes
> + ;;
> + yes,no)
> + AC_MSG_ERROR([GLAMOR requested, but glamor and/or gbm not found.])
> + ;;
> + no,*)
> + ;;
> + *)
> + AC_MSG_NOTICE([GLAMOR disabled because glamor and/or gbm not found.])
> + GLAMOR=no
> + ;;
> +esac
> +
> +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..76bf422 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);
>
More information about the xorg-devel
mailing list