[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