[virglrenderer-devel] [PATCH 1/2] virgl/egl: Add option to use the surfaceless platform

Tomeu Vizoso tomeu.vizoso at collabora.com
Mon Jul 30 13:56:45 UTC 2018


To make it easier to run the test suite on environments without graphics
hardware, add an environment variable VIRGL_EGL_SURFACELESS that will
force the use of the surfaceless platform.

Combined with the following flags, we can run virglrenderer and its
tests without any graphics hardware or windowing system present:

LIBGL_ALWAYS_SOFTWARE=true GALLIUM_DRIVER=llvmpipe VIRGL_EGL_SURFACELESS=yes

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---
 src/virgl_egl.h         |  2 +-
 src/virgl_egl_context.c | 48 +++++++++++++++++++++++++++++------------
 src/virglrenderer.c     |  2 +-
 src/virglrenderer.h     |  1 +
 vtest/vtest_renderer.c  |  8 +++++++
 5 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/src/virgl_egl.h b/src/virgl_egl.h
index 3bda41883f94..fc69757700be 100644
--- a/src/virgl_egl.h
+++ b/src/virgl_egl.h
@@ -27,7 +27,7 @@
 #include "vrend_renderer.h"
 struct virgl_egl;
 
-struct virgl_egl *virgl_egl_init(int fd);
+struct virgl_egl *virgl_egl_init(int fd, bool surfaceless);
 void virgl_egl_destroy(struct virgl_egl *ve);
 
 virgl_renderer_gl_context virgl_egl_create_context(struct virgl_egl *ve, struct virgl_gl_ctx_param *vparams);
diff --git a/src/virgl_egl_context.c b/src/virgl_egl_context.c
index 04f300c92776..3f00e25b9cf8 100644
--- a/src/virgl_egl_context.c
+++ b/src/virgl_egl_context.c
@@ -123,9 +123,9 @@ static bool virgl_egl_has_extension_in_string(const char *haystack, const char *
    return false;
 }
 
-struct virgl_egl *virgl_egl_init(int fd)
+struct virgl_egl *virgl_egl_init(int fd, bool surfaceless)
 {
-   static const EGLint conf_att[] = {
+   static EGLint conf_att[] = {
       EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
       EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
       EGL_RED_SIZE, 1,
@@ -148,16 +148,22 @@ struct virgl_egl *virgl_egl_init(int fd)
    if (!d)
       return NULL;
 
-   if (fd >= 0) {
-      d->fd = fd;
+   if (surfaceless) {
+      conf_att[1] = EGL_PBUFFER_BIT;
+      d->fd = -1;
+      d->gbm_dev = NULL;
    } else {
-      d->fd = egl_rendernode_open();
+      if (fd >= 0) {
+         d->fd = fd;
+      } else {
+         d->fd = egl_rendernode_open();
+      }
+      if (d->fd == -1)
+         goto fail;
+      d->gbm_dev = gbm_create_device(d->fd);
+      if (!d->gbm_dev)
+         goto fail;
    }
-   if (d->fd == -1)
-      goto fail;
-   d->gbm_dev = gbm_create_device(d->fd);
-   if (!d->gbm_dev)
-      goto fail;
 
    const char *client_extensions = eglQueryString (NULL, EGL_EXTENSIONS);
 
@@ -165,14 +171,26 @@ struct virgl_egl *virgl_egl_init(int fd)
       PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display =
          (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress ("eglGetPlatformDisplay");
 
-      if (get_platform_display)
+      if (!get_platform_display)
+        goto fail;
+
+      if (surfaceless) {
+         d->egl_display = get_platform_display (EGL_PLATFORM_SURFACELESS_MESA,
+                                                EGL_DEFAULT_DISPLAY, NULL);
+      } else
          d->egl_display = get_platform_display (EGL_PLATFORM_GBM_KHR,
                                                 (EGLNativeDisplayType)d->gbm_dev, NULL);
    } else if (strstr (client_extensions, "EGL_EXT_platform_base")) {
       PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display =
          (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress ("eglGetPlatformDisplayEXT");
 
-      if (get_platform_display)
+      if (!get_platform_display)
+        goto fail;
+
+      if (surfaceless) {
+         d->egl_display = get_platform_display (EGL_PLATFORM_SURFACELESS_MESA,
+                                                EGL_DEFAULT_DISPLAY, NULL);
+      } else
          d->egl_display = get_platform_display (EGL_PLATFORM_GBM_KHR,
                                                 (EGLNativeDisplayType)d->gbm_dev, NULL);
    } else {
@@ -245,8 +263,10 @@ void virgl_egl_destroy(struct virgl_egl *d)
                   EGL_NO_CONTEXT);
    eglDestroyContext(d->egl_display, d->egl_ctx);
    eglTerminate(d->egl_display);
-   gbm_device_destroy(d->gbm_dev);
-   close(d->fd);
+   if (d->gbm_dev)
+      gbm_device_destroy(d->gbm_dev);
+   if (d->fd >= 0)
+      close(d->fd);
    free(d);
 }
 
diff --git a/src/virglrenderer.c b/src/virglrenderer.c
index 86824f8e0f20..e77cfce9c3e4 100644
--- a/src/virglrenderer.c
+++ b/src/virglrenderer.c
@@ -315,7 +315,7 @@ int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks
       if (cbs->version >= 2 && cbs->get_drm_fd) {
          fd = cbs->get_drm_fd(cookie);
       }
-      egl_info = virgl_egl_init(fd);
+      egl_info = virgl_egl_init(fd, flags & VIRGL_RENDERER_USE_SURFACELESS);
       if (!egl_info)
          return -1;
       use_context = CONTEXT_EGL;
diff --git a/src/virglrenderer.h b/src/virglrenderer.h
index b63d653ff99e..0371bee6b56c 100644
--- a/src/virglrenderer.h
+++ b/src/virglrenderer.h
@@ -66,6 +66,7 @@ struct virgl_renderer_callbacks {
  */
 #define VIRGL_RENDERER_THREAD_SYNC 2
 #define VIRGL_RENDERER_USE_GLX (1 << 2)
+#define VIRGL_RENDERER_USE_SURFACELESS (1 << 3)
 
 VIRGL_EXPORT int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cb);
 VIRGL_EXPORT void virgl_renderer_poll(void); /* force fences */
diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c
index 08b74bf1f3b8..f6f712a3020b 100644
--- a/vtest/vtest_renderer.c
+++ b/vtest/vtest_renderer.c
@@ -122,6 +122,14 @@ int vtest_create_renderer(int in_fd, int out_fd, uint32_t length)
     if (getenv("VTEST_USE_GLX"))
        ctx = VIRGL_RENDERER_USE_GLX;
 
+    if (getenv("VTEST_USE_EGL_SURFACELESS")) {
+        if (ctx & VIRGL_RENDERER_USE_GLX) {
+            fprintf(stderr, "Cannot use surfaceless with GLX.\n");
+            return -1;
+        }
+        ctx |= VIRGL_RENDERER_USE_SURFACELESS;
+    }
+
     ret = virgl_renderer_init(&renderer,
                               ctx | VIRGL_RENDERER_THREAD_SYNC, &vtest_cbs);
     if (ret) {
-- 
2.17.1



More information about the virglrenderer-devel mailing list