Add a GLX backend

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@redhat.com>
macos/master
Marc-André Lureau 9 years ago committed by Dave Airlie
parent c49117ab45
commit 209557f455
  1. 22
      configure.ac
  2. 10
      src/Makefile.am
  3. 38
      src/virgl_glx.h
  4. 109
      src/virgl_glx_context.c
  5. 57
      src/virglrenderer.c
  6. 1
      src/virglrenderer.h

@ -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
])

@ -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

@ -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

@ -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();
}

@ -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,8 +211,12 @@ 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;
@ -212,8 +228,12 @@ 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);
}
@ -221,8 +241,12 @@ static void destroy_gl_context(virgl_renderer_gl_context 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,10 +305,20 @@ 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
}

@ -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 */

Loading…
Cancel
Save