diff options
Diffstat (limited to 'xorg-server/glamor')
-rw-r--r-- | xorg-server/glamor/Makefile.am | 1 | ||||
-rw-r--r-- | xorg-server/glamor/glamor.c | 21 | ||||
-rw-r--r-- | xorg-server/glamor/glamor.h | 64 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_egl.c | 97 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_eglmodule.c | 3 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_xv.c | 19 |
6 files changed, 154 insertions, 51 deletions
diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am index 12a57c441..77492bcaa 100644 --- a/xorg-server/glamor/Makefile.am +++ b/xorg-server/glamor/Makefile.am @@ -37,7 +37,6 @@ libglamor_la_SOURCES = \ glamor_window.c\ glamor_fbo.c\ glamor_compositerects.c\ - glamor_xv.c\ glamor_utils.h\ glamor.h diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c index 7d8228cdd..fa753bb1a 100644 --- a/xorg-server/glamor/glamor.c +++ b/xorg-server/glamor/glamor.c @@ -123,6 +123,17 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap) glamor_priv->back_pixmap = back_pixmap; } +uint32_t +glamor_get_pixmap_texture(PixmapPtr pixmap) +{ + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY) + return 0; + + return pixmap_priv->base.fbo->tex; +} + PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) @@ -556,16 +567,16 @@ glamor_enable_dri3(ScreenPtr screen) } Bool -glamor_is_dri3_support_enabled(ScreenPtr screen) +glamor_supports_pixmap_import_export(ScreenPtr screen) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); return glamor_priv->dri3_enabled; } -int -glamor_dri3_fd_from_pixmap(ScreenPtr screen, - PixmapPtr pixmap, CARD16 *stride, CARD32 *size) +_X_EXPORT int +glamor_fd_from_pixmap(ScreenPtr screen, + PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = @@ -589,7 +600,7 @@ glamor_dri3_fd_from_pixmap(ScreenPtr screen, } int -glamor_dri3_name_from_pixmap(PixmapPtr pixmap) +glamor_name_from_pixmap(PixmapPtr pixmap) { glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h index eec687256..e12f497cb 100644 --- a/xorg-server/glamor/glamor.h +++ b/xorg-server/glamor/glamor.h @@ -35,6 +35,9 @@ #include <picturestr.h> #include <fb.h> #include <fbpict.h> +#ifdef GLAMOR_FOR_XORG +#include <xf86xv.h> +#endif struct glamor_context; @@ -64,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. * @@ -124,6 +129,8 @@ extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen); extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap); +extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap); + /* @glamor_glyphs_init: Initialize glyphs internal data structures. * * @pScreen: Current screen pointer. @@ -168,21 +175,23 @@ extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr, unsigned int, Bool, CARD16 *, CARD32 *); -/* @glamor_is_dri3_support_enabled: Returns if DRI3 support is enabled. +/* @glamor_supports_pixmap_import_export: Returns whether + * glamor_fd_from_pixmap(), glamor_name_from_pixmap(), and + * glamor_pixmap_from_fd() are supported. * * @screen: Current screen pointer. * - * To have DRI3 support enabled, glamor and glamor_egl need to be initialized, - * and glamor_egl_init_textured_pixmap need to be called. glamor also - * has to be compiled with gbm support. - * The EGL layer need to have the following extensions working: + * To have DRI3 support enabled, glamor and glamor_egl need to be + * initialized. glamor also has to be compiled with gbm support. + * + * The EGL layer needs to have the following extensions working: + * * .EGL_KHR_gl_texture_2D_image * .EGL_EXT_image_dma_buf_import - * If DRI3 support is not enabled, the following helpers will return an error. * */ -extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen); +extern _X_EXPORT Bool glamor_supports_pixmap_import_export(ScreenPtr screen); -/* @glamor_dri3_fd_from_pixmap: DRI3 helper to get a dma-buf fd from a pixmap. +/* @glamor_fd_from_pixmap: Get a dma-buf fd from a pixmap. * * @screen: Current screen pointer. * @pixmap: The pixmap from which we want the fd. @@ -193,22 +202,25 @@ extern _X_EXPORT Bool glamor_is_dri3_support_enabled(ScreenPtr screen); * content. * Returns the fd on success, -1 on error. * */ -extern _X_EXPORT int glamor_dri3_fd_from_pixmap(ScreenPtr screen, - PixmapPtr pixmap, - CARD16 *stride, CARD32 *size); +extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen, + PixmapPtr pixmap, + CARD16 *stride, CARD32 *size); -/* @glamor_dri3_name_from_pixmap: helper to get an gem name from a pixmap. +/** + * @glamor_name_from_pixmap: Gets a gem name from a pixmap. * * @pixmap: The pixmap from which we want the gem name. * - * the pixmap and the buffer associated by the gem name will share the same - * content. This function can be used by the DDX to support DRI2, but needs - * glamor DRI3 support to be activated. + * the pixmap and the buffer associated by the gem name will share the + * same content. This function can be used by the DDX to support DRI2, + * and needs the same set of buffer export GL extensions as DRI3 + * support. + * * Returns the name on success, -1 on error. * */ -extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap); +extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap); -/* @glamor_egl_dri3_pixmap_from_fd: DRI3 helper to get a pixmap from a dma-buf fd. +/* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd. * * @screen: Current screen pointer. * @fd: The dma-buf fd to import. @@ -220,13 +232,13 @@ extern _X_EXPORT int glamor_dri3_name_from_pixmap(PixmapPtr pixmap); * * Returns a valid pixmap if the import succeeded, else NULL. * */ -extern _X_EXPORT PixmapPtr glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, - int fd, - CARD16 width, - CARD16 height, - CARD16 stride, - CARD8 depth, - CARD8 bpp); +extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen, + int fd, + CARD16 width, + CARD16 height, + CARD16 stride, + CARD8 depth, + CARD8 bpp); #ifdef GLAMOR_FOR_XORG @@ -432,7 +444,7 @@ extern _X_EXPORT Bool glamor_poly_line_nf(DrawablePtr pDrawable, GCPtr pGC, extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points); -#if 0 +#ifdef GLAMOR_FOR_XORG extern _X_EXPORT XF86VideoAdaptorPtr glamor_xv_init(ScreenPtr pScreen, int num_texture_ports); #endif diff --git a/xorg-server/glamor/glamor_egl.c b/xorg-server/glamor/glamor_egl.c index 9dcba71ce..05e6bd02e 100644 --- a/xorg-server/glamor/glamor_egl.c +++ b/xorg-server/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; @@ -453,12 +455,12 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, #endif } -PixmapPtr -glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, - int fd, - CARD16 width, - CARD16 height, - CARD16 stride, CARD8 depth, CARD8 bpp) +_X_EXPORT PixmapPtr +glamor_pixmap_from_fd(ScreenPtr screen, + int fd, + CARD16 width, + CARD16 height, + CARD16 stride, CARD8 depth, CARD8 bpp) { #ifdef GLAMOR_HAS_GBM ScrnInfoPtr scrn = xf86ScreenToScrn(screen); @@ -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,30 @@ 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) { + /* Tell the core that we have the interfaces for import/export + * of pixmaps. + */ + glamor_enable_dri3(screen); + + /* If the driver wants to do its own auth dance (e.g. Xwayland + * on pre-3.15 kernels that don't have render nodes and thus + * has the wayland compositor as a master), then it needs us + * to stay out of the way and let it init DRI3 on its own. + */ + if (!(glamor_priv->flags & GLAMOR_NO_DRI3)) { + /* 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 +741,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/xorg-server/glamor/glamor_eglmodule.c b/xorg-server/glamor/glamor_eglmodule.c index 5ddd60235..d7e183649 100644 --- a/xorg-server/glamor/glamor_eglmodule.c +++ b/xorg-server/glamor/glamor_eglmodule.c @@ -30,6 +30,7 @@ #include "dix-config.h" #include <xorg-server.h> +#include <xf86.h> #define GLAMOR_FOR_XORG #include <xf86Module.h> #include "glamor.h" @@ -40,7 +41,7 @@ static XF86ModuleVersionInfo VersRec = { MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, - PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, + 1, 0, 0, /* version */ ABI_CLASS_ANSIC, /* Only need the ansic layer */ ABI_ANSIC_VERSION, MOD_CLASS_NONE, diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c index dc39476b5..fb9045747 100644 --- a/xorg-server/glamor/glamor_xv.c +++ b/xorg-server/glamor/glamor_xv.c @@ -32,10 +32,14 @@ * Xv acceleration implementation */ -#include "glamor_priv.h" +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif -#ifdef GLAMOR_XV #include "xf86xv.h" +#define GLAMOR_FOR_XORG +#include "glamor_priv.h" + #include <X11/extensions/Xv.h> #include "fourcc.h" /* Reference color space transform data */ @@ -430,7 +434,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn, Bool sync, RegionPtr clipBoxes, void *data, DrawablePtr pDrawable) { - ScreenPtr screen = xf86ScrnToScreen(pScrn); + ScreenPtr screen = pDrawable->pScreen; glamor_port_private *port_priv = (glamor_port_private *) data; INT32 x1, x2, y1, y2; int srcPitch, srcPitch2; @@ -614,12 +618,3 @@ glamor_xv_init(ScreenPtr screen, int num_texture_ports) } return adapt; } -#else -#if 0 -XF86VideoAdaptorPtr -glamor_xv_init(ScreenPtr screen, int num_texture_ports) -{ - return NULL; -} -#endif -#endif |