aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/glamor
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/glamor')
-rw-r--r--xorg-server/glamor/Makefile.am1
-rw-r--r--xorg-server/glamor/glamor.c21
-rw-r--r--xorg-server/glamor/glamor.h64
-rw-r--r--xorg-server/glamor/glamor_egl.c97
-rw-r--r--xorg-server/glamor/glamor_eglmodule.c3
-rw-r--r--xorg-server/glamor/glamor_xv.c19
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