vfb: add DRI3/glamor support
This commit adds DRI3/glamor support, effectively translating into hardware GPU support. Theoretically it should be possible to use DRM/GPU drivers such as virtio or vgem, although only the intel i915 driver is currently tested. Since Xvfb does no modeset, it opens the render node. Currently that is fixed to "/dev/dri/renderD128" and will be tweaked with future commits. Specific use-cases are left for the reader - testing glamor, GL driver or others. v2: Drop GLAMOR_NO_XV, use GLAMOR_FOR_XORG instead (Michel Dänzer) v3: Fix build w/o glamor v4: - Split out glamor dependency patch for meson (Pekka) - Enhance commit message (Pekka) - Use O_CLOEXEC with open() (Pekka) - Enhance error path, memory leak comments (Pekka) Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
This commit is contained in:
parent
9e574a5bd8
commit
b2a0d6065d
|
@ -68,6 +68,14 @@ from The Open Group.
|
|||
#include "glx_extinit.h"
|
||||
#include "randrstr.h"
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
#include <glamor.h>
|
||||
#include <gbm.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#define VFB_DEFAULT_WIDTH 1280
|
||||
#define VFB_DEFAULT_HEIGHT 1024
|
||||
#define VFB_DEFAULT_DEPTH 24
|
||||
|
@ -101,6 +109,12 @@ typedef struct {
|
|||
#ifdef HAS_SHM
|
||||
int shmid;
|
||||
#endif
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
int fd;
|
||||
CreateScreenResourcesProcPtr createScreenResources;
|
||||
struct gbm_device *gbm;
|
||||
struct gbm_bo *front_bo;
|
||||
#endif
|
||||
} vfbScreenInfo, *vfbScreenInfoPtr;
|
||||
|
||||
static int vfbNumScreens;
|
||||
|
@ -726,10 +740,110 @@ vfbCloseScreen(ScreenPtr pScreen)
|
|||
if (pScreen->devPrivate)
|
||||
(*pScreen->DestroyPixmap) (pScreen->devPrivate);
|
||||
pScreen->devPrivate = NULL;
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
if (pvfb->fd >= 0) {
|
||||
if (pvfb->front_bo) {
|
||||
gbm_bo_destroy(pvfb->front_bo);
|
||||
pvfb->front_bo = NULL;
|
||||
}
|
||||
close(pvfb->fd);
|
||||
pvfb->fd = -1;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* XXX: There is an existing vfbScreens leak. Should we free() it directly
|
||||
* or otherwise - input welcome.
|
||||
*/
|
||||
|
||||
return pScreen->CloseScreen(pScreen);
|
||||
}
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
static Bool
|
||||
vfbCreateScreenResources(ScreenPtr pScreen)
|
||||
{
|
||||
vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
|
||||
PixmapPtr pixmap;
|
||||
Bool ret;
|
||||
|
||||
pScreen->CreateScreenResources = pvfb->createScreenResources;
|
||||
ret = pScreen->CreateScreenResources(pScreen);
|
||||
pScreen->CreateScreenResources = vfbCreateScreenResources;
|
||||
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
pixmap = pScreen->GetScreenPixmap(pScreen);
|
||||
/* TODO: add support for modifiers at some point */
|
||||
if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, pvfb->front_bo,
|
||||
FALSE)) {
|
||||
LogMessage(X_ERROR, "glamor_egl_create_textured_pixmap() failed\n");
|
||||
/* TODO: plug the leak, aka undo the CreateScreenResources() call above. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
vfbDRIInit(ScreenPtr pScreen)
|
||||
{
|
||||
vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
|
||||
/* TODO: don't hardcode the node name */
|
||||
const char *node_name = "/dev/dri/renderD128";
|
||||
const char *error_msg;
|
||||
|
||||
pvfb->fd = open(node_name, O_RDWR | O_CLOEXEC);
|
||||
if (pvfb->fd < 0) {
|
||||
error_msg = "Failed to open device node";
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!glamor_egl_init(pScreen, pvfb->fd)) {
|
||||
error_msg = "Failed to initialize glamor";
|
||||
goto close_fd;
|
||||
}
|
||||
|
||||
pvfb->gbm = glamor_egl_get_gbm_device(pScreen);
|
||||
if (!pvfb->gbm) {
|
||||
error_msg = "Failed to get gbm device";
|
||||
goto egl_fini;
|
||||
}
|
||||
pvfb->front_bo = gbm_bo_create(pvfb->gbm,
|
||||
pScreen->width, pScreen->height,
|
||||
GBM_FORMAT_ARGB8888,
|
||||
GBM_BO_USE_RENDERING);
|
||||
if (!pvfb->front_bo) {
|
||||
error_msg = "Failed to create front buffer";
|
||||
goto egl_fini;
|
||||
}
|
||||
|
||||
if (!glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) {
|
||||
error_msg = "Failed to initialize glamor at ScreenInit() time";
|
||||
goto destroy_bo;
|
||||
}
|
||||
|
||||
pvfb->createScreenResources = pScreen->CreateScreenResources;
|
||||
pScreen->CreateScreenResources = vfbCreateScreenResources;
|
||||
return;
|
||||
|
||||
destroy_bo:
|
||||
gbm_bo_destroy(pvfb->front_bo);
|
||||
egl_fini:
|
||||
/* TODO: There's no glamor_egl_fini just yet */
|
||||
close_fd:
|
||||
close(pvfb->fd);
|
||||
out:
|
||||
LogMessage(X_ERROR, "%s. Disabling GLAMOR/DRI3.\n", error_msg);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
vfbDRIInit(ScreenPtr pScreen)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static Bool
|
||||
vfbRROutputValidateMode(ScreenPtr pScreen,
|
||||
RROutputPtr output,
|
||||
|
@ -925,8 +1039,10 @@ vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
|
|||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
if (Render)
|
||||
if (Render) {
|
||||
fbPictureInit(pScreen, 0, 0);
|
||||
vfbDRIInit(pScreen);
|
||||
}
|
||||
|
||||
if (!vfbRandRInit(pScreen))
|
||||
return FALSE;
|
||||
|
|
|
@ -4,6 +4,10 @@ bin_PROGRAMS = Xvfb
|
|||
|
||||
AM_CFLAGS = -DHAVE_DIX_CONFIG_H \
|
||||
$(XVFBMODULES_CFLAGS) \
|
||||
-I$(top_srcdir)/glamor/ \
|
||||
-I$(top_srcdir)/dri3/ \
|
||||
$(LIBDRM_CFLAGS) \
|
||||
$(GBM_CFLAGS) \
|
||||
$(DIX_CFLAGS)
|
||||
|
||||
SRCS = InitInput.c \
|
||||
|
@ -13,6 +17,7 @@ SRCS = InitInput.c \
|
|||
Xvfb_SOURCES = $(SRCS)
|
||||
|
||||
XVFB_LIBS = \
|
||||
$(glamor_lib) \
|
||||
@XVFB_LIBS@ \
|
||||
$(MAIN_LIB) \
|
||||
$(XSERVER_LIBS) \
|
||||
|
@ -22,5 +27,13 @@ Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS)
|
|||
Xvfb_DEPENDENCIES = $(XVFB_LIBS)
|
||||
Xvfb_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
|
||||
|
||||
if GLAMOR_EGL
|
||||
Xvfb_SOURCES += $(top_srcdir)/glamor/glamor_egl.c
|
||||
glamor_lib = $(top_builddir)/glamor/libglamor.la
|
||||
|
||||
Xvfb_LDADD += $(GLAMOR_LIBS) $(GBM_LIBS) $(LIBDRM_LIBS) -lEGL -lGL
|
||||
Xvfb_DEPENDENCIES = $(glamor_lib) $(XVFB_LIBS)
|
||||
endif
|
||||
|
||||
relink:
|
||||
$(AM_V_at)rm -f Xvfb$(EXEEXT) && $(MAKE) Xvfb$(EXEEXT)
|
||||
|
|
|
@ -4,12 +4,27 @@ srcs = [
|
|||
'../../mi/miinitext.c',
|
||||
]
|
||||
|
||||
vfb_dep = []
|
||||
vfb_glamor = []
|
||||
if build_glamor
|
||||
srcs += '../../glamor/glamor_egl.c'
|
||||
vfb_dep += [
|
||||
libdrm_dep,
|
||||
gbm_dep,
|
||||
]
|
||||
vfb_glamor += glamor
|
||||
endif
|
||||
|
||||
xvfb_server = executable(
|
||||
'Xvfb',
|
||||
srcs,
|
||||
include_directories: inc,
|
||||
dependencies: common_dep,
|
||||
dependencies: [
|
||||
common_dep,
|
||||
vfb_dep,
|
||||
],
|
||||
link_with: [
|
||||
vfb_glamor,
|
||||
libxserver_main,
|
||||
libxserver_fb,
|
||||
libxserver,
|
||||
|
|
Loading…
Reference in New Issue
Block a user