[PATCH 6/6] glamor: Add support for DRI3.

davyaxel at free.fr davyaxel at free.fr
Mon Feb 24 23:56:50 PST 2014


Hi,

While for XWayland we want to provide our own dri3_open, we still want to have glamor
enabling the dri3 support

That is rather a GLAMOR_NO_DRI3_SETUP flag

and

+    if (glamor_egl->dri3_capable && !(glamor_priv->flags & GLAMOR_NO_DRI3)) {
+        /* Tell the core that we have the interfaces for import/export
+         * of pixmaps.
+         */
+        glamor_enable_dri3(screen);
+
+        /* To do DRI3 device FD generation, we need to open a new fd
+         * to the same device we were handed in originally.
+         */
+        glamor_egl->device_path = drmGetDeviceNameFromFd(glamor_egl->fd);
+
+        if (!dri3_screen_init(screen, &glamor_dri3_info)) {
+            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                       "Failed to initialize DRI3.\n");
+        }
+    }


would be like that:

+    if (glamor_egl->dri3_capable) {
+        /* Tell the core that we have the interfaces for import/export
+         * of pixmaps.
+         */
+        glamor_enable_dri3(screen);
+
+        if (!(glamor_priv->flags & GLAMOR_NO_DRI3_SETUP)) {
+            /* To do DRI3 device FD generation, we need to open a new fd
+             * to the same device we were handed in originally.
+             */
+            glamor_egl->device_path = drmGetDeviceNameFromFd(glamor_egl->fd);
+
+            if (!dri3_screen_init(screen, &glamor_dri3_info)) {
+                xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+                           "Failed to initialize DRI3.\n");
+            }
+        }
+    }

Otherwise, it looks fine.

Perhaps it would be better to detect if the device is a render-node or not,
and if it is a render-node, then prevent doing an IOCTL call for nothing.

Thanks,

Axel Davy

On 25/02/2014, Eric Anholt wrote :
> The render-nodes case is untested.
>
> v2: Add a flag for wayland to suppress the native DRI3 support.
>     Wayland isn't running as a master itself, so it can't do the auth
>     on its own and has to ask the compositor to do it for us.  Dropped
>     XXX about randr provider -- the conclusion from discussion with
>     keithp was that if the driver's dri3_open for a provider on a
>     different screen, that's a core dri3 bug.
>
> Signed-off-by: Eric Anholt <eric at anholt.net>
> ---
>  glamor/glamor.h                   |  4 +-
>  glamor/glamor_egl.c               | 78 +++++++++++++++++++++++++++++++++++++++
>  hw/xfree86/glamor_egl/Makefile.am |  5 ++-
>  3 files changed, 85 insertions(+), 2 deletions(-)
>
> diff --git a/glamor/glamor.h b/glamor/glamor.h
> index 20988f4..d3520ab 100644
> --- a/glamor/glamor.h
> +++ b/glamor/glamor.h
> @@ -67,10 +67,12 @@ typedef enum glamor_pixmap_type {
>  #define GLAMOR_USE_SCREEN		(1 << 1)
>  #define GLAMOR_USE_PICTURE_SCREEN 	(1 << 2)
>  #define GLAMOR_USE_EGL_SCREEN		(1 << 3)
> +#define GLAMOR_NO_DRI3			(1 << 4)
>  #define GLAMOR_VALID_FLAGS      (GLAMOR_INVERTED_Y_AXIS  		\
>  				 | GLAMOR_USE_SCREEN 			\
>                                   | GLAMOR_USE_PICTURE_SCREEN		\
> -				 | GLAMOR_USE_EGL_SCREEN)
> +				 | GLAMOR_USE_EGL_SCREEN                \
> +                                 | GLAMOR_NO_DRI3)
>  
>  /* @glamor_init: Initialize glamor internal data structure.
>   *
> diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
> index 56d8913..c883777 100644
> --- a/glamor/glamor_egl.c
> +++ b/glamor/glamor_egl.c
> @@ -50,6 +50,7 @@
>  
>  #include "glamor.h"
>  #include "glamor_priv.h"
> +#include "dri3.h"
>  
>  static const char glamor_name[] = "glamor";
>  
> @@ -68,6 +69,7 @@ struct glamor_egl_screen_private {
>      EGLDisplay display;
>      EGLContext context;
>      EGLint major, minor;
> +    char *device_path;
>  
>      CreateScreenResourcesProcPtr CreateScreenResources;
>      CloseScreenProcPtr CloseScreen;
> @@ -627,10 +629,67 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
>      return FALSE;
>  }
>  
> +static int
> +glamor_dri3_open(ScreenPtr screen,
> +                 RRProviderPtr provider,
> +                 int *fdp)
> +{
> +    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> +    struct glamor_egl_screen_private *glamor_egl =
> +        glamor_egl_get_screen_private(scrn);
> +    int fd;
> +    drm_magic_t magic;
> +
> +    fd = open(glamor_egl->device_path, O_RDWR|O_CLOEXEC);
> +    if (fd < 0)
> +        return BadAlloc;
> +
> +    /* Before FD passing in the X protocol with DRI3 (and increased
> +     * security of rendering with per-process address spaces on the
> +     * GPU), the kernel had to come up with a way to have the server
> +     * decide which clients got to access the GPU, which was done by
> +     * each client getting a unique (magic) number from the kernel,
> +     * passing it to the server, and the server then telling the
> +     * kernel which clients were authenticated for using the device.
> +     *
> +     * Now that we have FD passing, the server can just set up the
> +     * authentication on its own and hand the prepared FD off to the
> +     * client.
> +     */
> +    if (drmGetMagic(fd, &magic) < 0) {
> +        if (errno == EACCES) {
> +            /* Assume that we're on a render node, and the fd is
> +             * already as authenticated as it should be.
> +             */
> +            *fdp = fd;
> +            return Success;
> +        } else {
> +            close(fd);
> +            return BadMatch;
> +        }
> +    }
> +
> +    if (drmAuthMagic(glamor_egl->fd, magic) < 0) {
> +        close(fd);
> +        return BadMatch;
> +    }
> +
> +    *fdp = fd;
> +    return Success;
> +}
> +
> +static dri3_screen_info_rec glamor_dri3_info = {
> +    .version = 0,
> +    .open = glamor_dri3_open,
> +    .pixmap_from_fd = glamor_pixmap_from_fd,
> +    .fd_from_pixmap = glamor_fd_from_pixmap,
> +};
> +
>  void
>  glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
>  {
>      ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> +    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
>      struct glamor_egl_screen_private *glamor_egl =
>          glamor_egl_get_screen_private(scrn);
>  
> @@ -642,6 +701,23 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
>  
>      glamor_ctx->get_context = glamor_egl_get_context;
>      glamor_ctx->put_context = glamor_egl_put_context;
> +
> +    if (glamor_egl->dri3_capable && !(glamor_priv->flags & GLAMOR_NO_DRI3)) {
> +        /* Tell the core that we have the interfaces for import/export
> +         * of pixmaps.
> +         */
> +        glamor_enable_dri3(screen);
> +
> +        /* To do DRI3 device FD generation, we need to open a new fd
> +         * to the same device we were handed in originally.
> +         */
> +        glamor_egl->device_path = drmGetDeviceNameFromFd(glamor_egl->fd);
> +
> +        if (!dri3_screen_init(screen, &glamor_dri3_info)) {
> +            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
> +                       "Failed to initialize DRI3.\n");
> +        }
> +    }
>  }
>  
>  static void
> @@ -658,6 +734,8 @@ glamor_egl_free_screen(ScrnInfoPtr scrn)
>          if (glamor_egl->gbm)
>              gbm_device_destroy(glamor_egl->gbm);
>  #endif
> +        free(glamor_egl->device_path);
> +
>          scrn->FreeScreen = glamor_egl->saved_free_screen;
>          free(glamor_egl);
>          scrn->FreeScreen(scrn);
> diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am
> index bb1b511..85e1c0c 100644
> --- a/hw/xfree86/glamor_egl/Makefile.am
> +++ b/hw/xfree86/glamor_egl/Makefile.am
> @@ -36,5 +36,8 @@ libglamoregl_la_LIBADD = \
>  	$(top_builddir)/glamor/libglamor.la \
>  	$()
>  
> -AM_CPPFLAGS = $(XORG_INCS)
> +AM_CPPFLAGS = $(XORG_INCS) \
> +	-I$(top_srcdir)/dri3 \
> +	$()
> +
>  AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)


More information about the xorg-devel mailing list