[virglrenderer-devel] [PATCH 1/4] Add a GLX backend
marcandre.lureau at redhat.com
marcandre.lureau at redhat.com
Fri Jun 10 17:25:00 UTC 2016
From: Marc-André Lureau <marcandre.lureau at redhat.com>
apitrace & epoxy with EGL don't work nicely together, using glx works
around this issue for now (disabled by default).
Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
---
configure.ac | 22 ++++++++++
src/Makefile.am | 10 ++++-
src/virgl_glx.h | 38 +++++++++++++++++
src/virgl_glx_context.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++
src/virglrenderer.c | 57 +++++++++++++++++++++----
src/virglrenderer.h | 1 +
6 files changed, 228 insertions(+), 9 deletions(-)
create mode 100644 src/virgl_glx.h
create mode 100644 src/virgl_glx_context.c
diff --git a/configure.ac b/configure.ac
index 3f25f06..1256eb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -102,6 +102,13 @@ fi
PKG_CHECK_MODULES([EPOXY], [epoxy])
+AC_ARG_WITH([glx], AS_HELP_STRING([--with-glx], [Build with the x11/glx backend]))
+AS_IF([test "x$with_glx" = "xyes"], [
+ PKG_CHECK_MODULES([X11], [x11])
+ AC_CHECK_HEADER([epoxy/glx.h])
+])
+AM_CONDITIONAL([WITH_GLX], [test "x$with_glx" = "xyes"])
+
AC_SUBST([DEFINES])
AC_CONFIG_FILES([
virglrenderer.pc
@@ -112,3 +119,18 @@ AC_CONFIG_FILES([
tests/Makefile
])
AC_OUTPUT
+
+AC_MSG_NOTICE([
+
+ virgl $VERSION
+ ==============
+
+ prefix: $prefix
+ c compiler: $CC
+ win32: $os_win32
+
+ glx: $with_glx
+ debug: $enable_debug
+ tests: $build_tests
+
+])
diff --git a/src/Makefile.am b/src/Makefile.am
index 0b564f2..3ec8358 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,6 +2,7 @@ SUBDIRS := gallium/auxiliary
AM_LDFLAGS = -lm \
$(GBM_LIBS) \
$(EPOXY_LIBS) \
+ $(X11_LIBS) \
$(CODE_COVERAGE_LDFLAGS)
AM_CFLAGS = \
@@ -12,6 +13,7 @@ AM_CFLAGS = \
$(LIBDRM_CFLAGS) \
$(GBM_CFLAGS) \
$(EPOXY_CFLAGS) \
+ $(X11_CFLAGS) \
$(VISIBILITY_CFLAGS) \
$(CODE_COVERAGE_CFLAGS)
@@ -37,6 +39,12 @@ libvrend_la_SOURCES += \
virgl_egl_context.c
endif
+if WITH_GLX
+libvrend_la_SOURCES += \
+ virgl_glx.h \
+ virgl_glx_context.c
+endif
+
lib_LTLIBRARIES = libvirglrenderer.la
noinst_LTLIBRARIES = libvrend.la
@@ -45,7 +53,7 @@ GM_LDFLAGS = -Wl,-Bsymbolic -version-number 0:2 -no-undefined
libvirglrenderer_la_SOURCES = virglrenderer.c
libvirglrenderer_ladir = $(libdir)
libvirglrenderer_la_LIBADD = libvrend.la gallium/auxiliary/libgallium.la
-libvirglrenderer_la_LDFLAGS = $(GM_LDFLAGS) $(EPOXY_LDFLAGS)
+libvirglrenderer_la_LDFLAGS = $(GM_LDFLAGS) $(EPOXY_LDFLAGS) $(X11_LDFLAGS)
libvirglrendererincludedir = ${includedir}/virgl
libvirglrendererinclude_HEADERS = virglrenderer.h
diff --git a/src/virgl_glx.h b/src/virgl_glx.h
new file mode 100644
index 0000000..50c0bdd
--- /dev/null
+++ b/src/virgl_glx.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+#ifndef VIRGL_GLX_H
+#define VIRGL_GLX_H
+
+#include "vrend_renderer.h"
+struct virgl_glx;
+
+struct virgl_glx *virgl_glx_init(void);
+void virgl_glx_destroy(struct virgl_glx *ve);
+
+virgl_renderer_gl_context virgl_glx_create_context(struct virgl_glx *ve, struct virgl_gl_ctx_param *vparams);
+void virgl_glx_destroy_context(struct virgl_glx *ve, virgl_renderer_gl_context virglctx);
+int virgl_glx_make_context_current(struct virgl_glx *ve, virgl_renderer_gl_context virglctx);
+virgl_renderer_gl_context virgl_glx_get_current_context(struct virgl_glx *ve);
+
+#endif
diff --git a/src/virgl_glx_context.c b/src/virgl_glx_context.c
new file mode 100644
index 0000000..4bc98dc
--- /dev/null
+++ b/src/virgl_glx_context.c
@@ -0,0 +1,109 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <epoxy/glx.h>
+#include "virglrenderer.h"
+#include "virgl_glx.h"
+
+struct virgl_glx {
+ Display *display;
+ GLXFBConfig* fbConfigs;
+ GLXPbuffer pbuffer;
+};
+
+struct virgl_glx *virgl_glx_init(void)
+{
+ struct virgl_glx *d;
+
+ d = malloc(sizeof(struct virgl_glx));
+ if (!d)
+ return NULL;
+
+ d->display = XOpenDisplay(NULL);
+
+ if (!d->display) {
+ free(d);
+ return NULL;
+ }
+
+ int visualAttribs[] = { None };
+ int numberOfFramebufferConfigurations = 0;
+
+ d->fbConfigs = glXChooseFBConfig(d->display, DefaultScreen(d->display),
+ visualAttribs, &numberOfFramebufferConfigurations);
+
+ int pbufferAttribs[] = {
+ GLX_PBUFFER_WIDTH, 32,
+ GLX_PBUFFER_HEIGHT, 32,
+ None
+ };
+ d->pbuffer = glXCreatePbuffer(d->display, d->fbConfigs[0], pbufferAttribs);
+
+ return d;
+}
+
+void virgl_glx_destroy(struct virgl_glx *d)
+{
+ XFree(d->fbConfigs);
+ glXDestroyPbuffer(d->display,d->pbuffer);
+ XCloseDisplay(d->display);
+ free(d);
+}
+
+virgl_renderer_gl_context virgl_glx_create_context(struct virgl_glx *d, struct virgl_gl_ctx_param *vparams)
+{
+ int context_attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, vparams->major_ver,
+ GLX_CONTEXT_MINOR_VERSION_ARB, vparams->minor_ver,
+ None
+ };
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(d->display, d->fbConfigs[0],
+ vparams->shared ? glXGetCurrentContext() : NULL,
+ True, context_attribs);
+ return (virgl_renderer_gl_context)ctx;
+}
+
+void virgl_glx_destroy_context(struct virgl_glx *d, virgl_renderer_gl_context virglctx)
+{
+ GLXContext ctx = (GLXContext)virglctx;
+
+ glXDestroyContext(d->display,ctx);
+}
+
+int virgl_glx_make_context_current(struct virgl_glx *d, virgl_renderer_gl_context virglctx)
+{
+ return glXMakeContextCurrent(d->display, d->pbuffer, d->pbuffer, virglctx);
+}
+
+virgl_renderer_gl_context virgl_glx_get_current_context(struct virgl_glx *d)
+{
+ return glXGetCurrentContext();
+}
diff --git a/src/virglrenderer.c b/src/virglrenderer.c
index 2801c7f..c89cb60 100644
--- a/src/virglrenderer.c
+++ b/src/virglrenderer.c
@@ -41,9 +41,21 @@
#ifdef HAVE_EPOXY_EGL_H
#include "virgl_egl.h"
static struct virgl_egl *egl_info;
-static int use_egl_context;
#endif
+#ifdef HAVE_EPOXY_GLX_H
+#include "virgl_glx.h"
+static struct virgl_glx *glx_info;
+#endif
+
+enum {
+ CONTEXT_NONE,
+ CONTEXT_EGL,
+ CONTEXT_GLX
+};
+
+static int use_context = CONTEXT_NONE;
+
/* new API - just wrap internal API for now */
int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs)
@@ -163,7 +175,7 @@ int virgl_renderer_resource_get_info(int res_handle,
int ret;
ret = vrend_renderer_resource_get_info(res_handle, (struct vrend_renderer_resource_info *)info);
#ifdef HAVE_EPOXY_EGL_H
- if (ret == 0 && use_egl_context)
+ if (ret == 0 && use_context == CONTEXT_EGL)
return virgl_egl_get_fourcc_for_texture(egl_info, info->tex_id, info->virgl_format, &info->drm_fourcc);
#endif
@@ -199,9 +211,13 @@ static virgl_renderer_gl_context create_gl_context(int scanout_idx, struct virgl
struct virgl_renderer_gl_ctx_param vparam;
#ifdef HAVE_EPOXY_EGL_H
- if (use_egl_context)
+ if (use_context == CONTEXT_EGL)
return virgl_egl_create_context(egl_info, param);
#endif
+#ifdef HAVE_EPOXY_GLX_H
+ if (use_context == CONTEXT_GLX)
+ return virgl_glx_create_context(glx_info, param);
+#endif
vparam.version = 1;
vparam.shared = param->shared;
vparam.major_ver = param->major_ver;
@@ -212,18 +228,26 @@ static virgl_renderer_gl_context create_gl_context(int scanout_idx, struct virgl
static void destroy_gl_context(virgl_renderer_gl_context ctx)
{
#ifdef HAVE_EPOXY_EGL_H
- if (use_egl_context)
+ if (use_context == CONTEXT_EGL)
return virgl_egl_destroy_context(egl_info, ctx);
#endif
+#ifdef HAVE_EPOXY_GLX_H
+ if (use_context == CONTEXT_GLX)
+ return virgl_glx_destroy_context(glx_info, ctx);
+#endif
return rcbs->destroy_gl_context(dev_cookie, ctx);
}
static int make_current(int scanout_idx, virgl_renderer_gl_context ctx)
{
#ifdef HAVE_EPOXY_EGL_H
- if (use_egl_context)
+ if (use_context == CONTEXT_EGL)
return virgl_egl_make_context_current(egl_info, ctx);
#endif
+#ifdef HAVE_EPOXY_GLX_H
+ if (use_context == CONTEXT_GLX)
+ return virgl_glx_make_context_current(glx_info, ctx);
+#endif
return rcbs->make_current(dev_cookie, scanout_idx, ctx);
}
@@ -249,10 +273,17 @@ void virgl_renderer_cleanup(void *cookie)
{
vrend_renderer_fini();
#ifdef HAVE_EPOXY_EGL_H
- if (use_egl_context) {
+ if (use_context == CONTEXT_EGL) {
virgl_egl_destroy(egl_info);
egl_info = NULL;
- use_egl_context = 0;
+ use_context = CONTEXT_NONE;
+ }
+#endif
+#ifdef HAVE_EPOXY_GLX_H
+ if (use_context == CONTEXT_GLX) {
+ virgl_glx_destroy(glx_info);
+ glx_info = NULL;
+ use_context = CONTEXT_NONE;
}
#endif
}
@@ -274,11 +305,21 @@ int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks
egl_info = virgl_egl_init();
if (!egl_info)
return -1;
- use_egl_context = 1;
+ use_context = CONTEXT_EGL;
#else
fprintf(stderr, "EGL is not supported on this platform\n");
return -1;
#endif
+ } else if (flags & VIRGL_RENDERER_USE_GLX) {
+#ifdef HAVE_EPOXY_GLX_H
+ glx_info = virgl_glx_init();
+ if (!glx_info)
+ return -1;
+ use_context = CONTEXT_GLX;
+#else
+ fprintf(stderr, "GLX is not supported on this platform\n");
+ return -1;
+#endif
}
if (flags & VIRGL_RENDERER_THREAD_SYNC)
diff --git a/src/virglrenderer.h b/src/virglrenderer.h
index c6dc055..6eb7bdb 100644
--- a/src/virglrenderer.h
+++ b/src/virglrenderer.h
@@ -61,6 +61,7 @@ struct virgl_renderer_callbacks {
* need to use virgl_renderer_get_poll_fd to know if this feature is in effect.
*/
#define VIRGL_RENDERER_THREAD_SYNC 2
+#define VIRGL_RENDERER_USE_GLX (1 << 2)
VIRGL_EXPORT int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cb);
VIRGL_EXPORT void virgl_renderer_poll(void); /* force fences */
--
2.7.4
More information about the virglrenderer-devel
mailing list