[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