glamor: Add support for DRI3.
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. v3: Don't put quite so much under GLAMOR_NO_DRI3, and add a comment explaining what this is about. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
fb4a1e6ef6
commit
da08316605
|
@ -67,10 +67,12 @@ typedef enum glamor_pixmap_type {
|
||||||
#define GLAMOR_USE_SCREEN (1 << 1)
|
#define GLAMOR_USE_SCREEN (1 << 1)
|
||||||
#define GLAMOR_USE_PICTURE_SCREEN (1 << 2)
|
#define GLAMOR_USE_PICTURE_SCREEN (1 << 2)
|
||||||
#define GLAMOR_USE_EGL_SCREEN (1 << 3)
|
#define GLAMOR_USE_EGL_SCREEN (1 << 3)
|
||||||
|
#define GLAMOR_NO_DRI3 (1 << 4)
|
||||||
#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \
|
#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \
|
||||||
| GLAMOR_USE_SCREEN \
|
| GLAMOR_USE_SCREEN \
|
||||||
| GLAMOR_USE_PICTURE_SCREEN \
|
| GLAMOR_USE_PICTURE_SCREEN \
|
||||||
| GLAMOR_USE_EGL_SCREEN)
|
| GLAMOR_USE_EGL_SCREEN \
|
||||||
|
| GLAMOR_NO_DRI3)
|
||||||
|
|
||||||
/* @glamor_init: Initialize glamor internal data structure.
|
/* @glamor_init: Initialize glamor internal data structure.
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
|
|
||||||
#include "glamor.h"
|
#include "glamor.h"
|
||||||
#include "glamor_priv.h"
|
#include "glamor_priv.h"
|
||||||
|
#include "dri3.h"
|
||||||
|
|
||||||
static const char glamor_name[] = "glamor";
|
static const char glamor_name[] = "glamor";
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ struct glamor_egl_screen_private {
|
||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
EGLint major, minor;
|
EGLint major, minor;
|
||||||
|
char *device_path;
|
||||||
|
|
||||||
CreateScreenResourcesProcPtr CreateScreenResources;
|
CreateScreenResourcesProcPtr CreateScreenResources;
|
||||||
CloseScreenProcPtr CloseScreen;
|
CloseScreenProcPtr CloseScreen;
|
||||||
|
@ -627,10 +629,67 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
|
||||||
return FALSE;
|
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
|
void
|
||||||
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
|
glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
|
||||||
{
|
{
|
||||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
struct glamor_egl_screen_private *glamor_egl =
|
struct glamor_egl_screen_private *glamor_egl =
|
||||||
glamor_egl_get_screen_private(scrn);
|
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->get_context = glamor_egl_get_context;
|
||||||
glamor_ctx->put_context = glamor_egl_put_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
|
static void
|
||||||
|
@ -658,6 +741,8 @@ glamor_egl_free_screen(ScrnInfoPtr scrn)
|
||||||
if (glamor_egl->gbm)
|
if (glamor_egl->gbm)
|
||||||
gbm_device_destroy(glamor_egl->gbm);
|
gbm_device_destroy(glamor_egl->gbm);
|
||||||
#endif
|
#endif
|
||||||
|
free(glamor_egl->device_path);
|
||||||
|
|
||||||
scrn->FreeScreen = glamor_egl->saved_free_screen;
|
scrn->FreeScreen = glamor_egl->saved_free_screen;
|
||||||
free(glamor_egl);
|
free(glamor_egl);
|
||||||
scrn->FreeScreen(scrn);
|
scrn->FreeScreen(scrn);
|
||||||
|
|
|
@ -36,5 +36,8 @@ libglamoregl_la_LIBADD = \
|
||||||
$(top_builddir)/glamor/libglamor.la \
|
$(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)
|
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user