All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support
@ 2016-02-18  9:26 Gerd Hoffmann
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 1/8] configure: add dma-buf support detection Gerd Hoffmann
                   ` (8 more replies)
  0 siblings, 9 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

  Hi,

This patch series adds support for opengl and dma-buf passing to spice.
With this in place you can use virtio-gpu in 3d (virgl) mode with spice.
Not fully clear whenever the last patch (tagged as RfC) is actually
needed.

please review,
  Gerd

Gerd Hoffmann (7):
  configure: add dma-buf support detection.
  egl-helpers: add functions for render nodes and dma-buf passing
  console: track gl_block state in QemuConsole
  spice: add opengl/virgl/dmabuf support
  spice: tweak debug messages.
  spice/gl: render DisplaySurface via opengl
  spice/gl: create dummy primary surface (RfC)

Marc-André Lureau (1):
  spice: reset cursor on resize

 configure                  |  20 +++-
 include/ui/console.h       |   1 +
 include/ui/egl-helpers.h   |  13 +++
 include/ui/spice-display.h |  20 ++++
 qemu-options.hx            |   4 +
 ui/console.c               |  15 ++-
 ui/egl-helpers.c           | 129 +++++++++++++++++++++++++
 ui/spice-core.c            |  18 +++-
 ui/spice-display.c         | 230 +++++++++++++++++++++++++++++++++++++++++++--
 9 files changed, 437 insertions(+), 13 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 1/8] configure: add dma-buf support detection.
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18 12:30   ` Marc-André Lureau
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 2/8] egl-helpers: add functions for render nodes and dma-buf passing Gerd Hoffmann
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

Set CONFIG_OPENGL_DMABUF in case both mesa and libepoxy are
new enough to have support for dma-buf import/export.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 configure | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 0aa249b..0c0472a 100755
--- a/configure
+++ b/configure
@@ -279,6 +279,7 @@ smartcard=""
 libusb=""
 usb_redir=""
 opengl=""
+opengl_dmabuf="no"
 zlib="yes"
 lzo=""
 snappy=""
@@ -3274,7 +3275,7 @@ libs_softmmu="$libs_softmmu $fdt_libs"
 # opengl probe (for sdl2, gtk, milkymist-tmu2)
 
 if test "$opengl" != "no" ; then
-  opengl_pkgs="epoxy"
+  opengl_pkgs="epoxy libdrm gbm"
   if $pkg_config $opengl_pkgs x11; then
     opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
     opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
@@ -3292,6 +3293,18 @@ if test "$opengl" != "no" ; then
   fi
 fi
 
+if test "$opengl" = "yes"; then
+  cat > $TMPC << EOF
+#include <epoxy/egl.h>
+#ifndef EGL_MESA_image_dma_buf_export
+# error mesa/epoxy lacks support for dmabufs (mesa 10.6+)
+#endif
+int main(void) { return 0; }
+EOF
+  if compile_prog "" "" ; then
+    opengl_dmabuf=yes
+  fi
+fi
 
 ##########################################
 # archipelago probe
@@ -4752,6 +4765,7 @@ echo "smartcard support $smartcard"
 echo "libusb            $libusb"
 echo "usb net redir     $usb_redir"
 echo "OpenGL support    $opengl"
+echo "OpenGL dmabufs    $opengl_dmabuf"
 echo "libiscsi support  $libiscsi"
 echo "libnfs support    $libnfs"
 echo "build guest agent $guest_agent"
@@ -5050,6 +5064,7 @@ if test "$gtk" = "yes" ; then
   echo "CONFIG_GTK=y" >> $config_host_mak
   echo "CONFIG_GTKABI=$gtkabi" >> $config_host_mak
   echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak
+  echo "GTK_LIBS=$gtk_libs" >> $config_host_mak
   if test "$gtk_gl" = "yes" ; then
     echo "CONFIG_GTK_GL=y" >> $config_host_mak
   fi
@@ -5158,6 +5173,9 @@ if test "$opengl" = "yes" ; then
   echo "CONFIG_OPENGL=y" >> $config_host_mak
   echo "OPENGL_CFLAGS=$opengl_cflags" >> $config_host_mak
   echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak
+  if test "$opengl_dmabuf" = "yes" ; then
+    echo "CONFIG_OPENGL_DMABUF=y" >> $config_host_mak
+  fi
 fi
 
 if test "$lzo" = "yes" ; then
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 2/8] egl-helpers: add functions for render nodes and dma-buf passing
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 1/8] configure: add dma-buf support detection Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18 12:30   ` Marc-André Lureau
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 3/8] console: track gl_block state in QemuConsole Gerd Hoffmann
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

Adds helpers to open a drm render node and create a opengl
context for it.  Also add a helper to export a texture as
dma-buf.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/egl-helpers.h |  13 +++++
 ui/egl-helpers.c         | 129 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)

diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index 8c84398..03fcf4b 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -3,10 +3,23 @@
 
 #include <epoxy/gl.h>
 #include <epoxy/egl.h>
+#include <gbm.h>
 
 extern EGLDisplay *qemu_egl_display;
 extern EGLConfig qemu_egl_config;
 
+#ifdef CONFIG_OPENGL_DMABUF
+
+extern int qemu_egl_rn_fd;
+extern struct gbm_device *qemu_egl_rn_gbm_dev;
+extern EGLContext qemu_egl_rn_ctx;
+
+int qemu_egl_rendernode_open(void);
+int egl_rendernode_init(void);
+int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc);
+
+#endif
+
 EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
 
 int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug);
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 4c83834..54be44c 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -1,6 +1,8 @@
 #include "qemu/osdep.h"
 #include <glob.h>
+#include <dirent.h>
 
+#include "config-host.h"
 #include "ui/egl-helpers.h"
 
 EGLDisplay *qemu_egl_display;
@@ -20,6 +22,133 @@ static int egl_debug;
 
 /* ---------------------------------------------------------------------- */
 
+#ifdef CONFIG_OPENGL_DMABUF
+
+int qemu_egl_rn_fd;
+struct gbm_device *qemu_egl_rn_gbm_dev;
+EGLContext qemu_egl_rn_ctx;
+
+int qemu_egl_rendernode_open(void)
+{
+    DIR *dir;
+    struct dirent *e;
+    int r, fd;
+    char *p;
+
+    dir = opendir("/dev/dri");
+    if (!dir) {
+        return -1;
+    }
+
+    fd = -1;
+    while ((e = readdir(dir))) {
+        if (e->d_type != DT_CHR) {
+            continue;
+        }
+
+        if (strncmp(e->d_name, "renderD", 7)) {
+            continue;
+        }
+
+        r = asprintf(&p, "/dev/dri/%s", e->d_name);
+        if (r < 0) {
+            return -1;
+        }
+
+        r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
+        if (r < 0) {
+            free(p);
+            continue;
+        }
+        fd = r;
+        free(p);
+        break;
+    }
+
+    closedir(dir);
+    if (fd < 0) {
+        return -1;
+    }
+    return fd;
+}
+
+int egl_rendernode_init(void)
+{
+    qemu_egl_rn_fd = -1;
+
+    qemu_egl_rn_fd = qemu_egl_rendernode_open();
+    if (qemu_egl_rn_fd == -1) {
+        fprintf(stderr, "egl: no drm render node available\n");
+        goto err;
+    }
+
+    qemu_egl_rn_gbm_dev = gbm_create_device(qemu_egl_rn_fd);
+    if (!qemu_egl_rn_gbm_dev) {
+        fprintf(stderr, "egl: gbm_create_device failed\n");
+        goto err;
+    }
+
+    qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev, false, false);
+
+    if (!epoxy_has_egl_extension(qemu_egl_display,
+                                 "EGL_KHR_surfaceless_context")) {
+        fprintf(stderr, "egl: EGL_KHR_surfaceless_context not supported\n");
+        goto err;
+    }
+    if (!epoxy_has_egl_extension(qemu_egl_display,
+                                 "EGL_MESA_image_dma_buf_export")) {
+        fprintf(stderr, "egl: EGL_MESA_image_dma_buf_export not supported\n");
+        goto err;
+    }
+
+    qemu_egl_rn_ctx = qemu_egl_init_ctx();
+    if (!qemu_egl_rn_ctx) {
+        fprintf(stderr, "egl: egl_init_ctx failed\n");
+        goto err;
+    }
+
+    return 0;
+
+err:
+    if (qemu_egl_rn_gbm_dev) {
+        gbm_device_destroy(qemu_egl_rn_gbm_dev);
+    }
+    if (qemu_egl_rn_fd != -1) {
+        close(qemu_egl_rn_fd);
+    }
+
+    return -1;
+}
+
+int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc)
+{
+    EGLImageKHR image;
+    EGLint num_planes, fd;
+
+    image = eglCreateImageKHR(qemu_egl_display, eglGetCurrentContext(),
+                              EGL_GL_TEXTURE_2D_KHR,
+                              (EGLClientBuffer)(unsigned long)tex_id,
+                              NULL);
+    if (!image) {
+        return -1;
+    }
+
+    eglExportDMABUFImageQueryMESA(qemu_egl_display, image, fourcc,
+                                  &num_planes, NULL);
+    if (num_planes != 1) {
+        eglDestroyImageKHR(qemu_egl_display, image);
+        return -1;
+    }
+    eglExportDMABUFImageMESA(qemu_egl_display, image, &fd, stride, NULL);
+    eglDestroyImageKHR(qemu_egl_display, image);
+
+    return fd;
+}
+
+#endif /* CONFIG_OPENGL_DMABUF */
+
+/* ---------------------------------------------------------------------- */
+
 EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
 {
     EGLSurface esurface;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 3/8] console: track gl_block state in QemuConsole
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 1/8] configure: add dma-buf support detection Gerd Hoffmann
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 2/8] egl-helpers: add functions for render nodes and dma-buf passing Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18 12:30   ` Marc-André Lureau
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 4/8] spice: reset cursor on resize Gerd Hoffmann
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

Keep track of gl_block state (added in bba19b8 console: block rendering
until client is done) in QemuConsole and allow to query it.  This way
we can avoid state inconsistencies in case different code paths make use
of this.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |  1 +
 ui/console.c         | 15 +++++++++++----
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index c8f9f7e..9672ad9 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -382,6 +382,7 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head);
 bool qemu_console_is_visible(QemuConsole *con);
 bool qemu_console_is_graphic(QemuConsole *con);
 bool qemu_console_is_fixedsize(QemuConsole *con);
+bool qemu_console_is_gl_blocked(QemuConsole *con);
 char *qemu_console_get_label(QemuConsole *con);
 int qemu_console_get_index(QemuConsole *con);
 uint32_t qemu_console_get_head(QemuConsole *con);
diff --git a/ui/console.c b/ui/console.c
index b739ae9..215c98d 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -123,6 +123,7 @@ struct QemuConsole {
     DisplaySurface *surface;
     int dcls;
     DisplayChangeListener *gl;
+    bool gl_block;
 
     /* Graphic console state.  */
     Object *device;
@@ -264,10 +265,10 @@ void graphic_hw_update(QemuConsole *con)
 
 void graphic_hw_gl_block(QemuConsole *con, bool block)
 {
-    if (!con) {
-        con = active_console;
-    }
-    if (con && con->hw_ops->gl_block) {
+    assert(con != NULL);
+
+    con->gl_block = block;
+    if (con->hw_ops->gl_block) {
         con->hw_ops->gl_block(con->hw, block);
     }
 }
@@ -1811,6 +1812,12 @@ bool qemu_console_is_fixedsize(QemuConsole *con)
     return con && (con->console_type != TEXT_CONSOLE);
 }
 
+bool qemu_console_is_gl_blocked(QemuConsole *con)
+{
+    assert(con != NULL);
+    return con->gl_block;
+}
+
 char *qemu_console_get_label(QemuConsole *con)
 {
     if (con->console_type == GRAPHIC_CONSOLE) {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 4/8] spice: reset cursor on resize
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 3/8] console: track gl_block state in QemuConsole Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel
  Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann,
	Marc-André Lureau

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Spice server will clear the cursor on resize. QXL driver reset it after
resize, however, virtio and other devices do not. Teach qemu to set it
back.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-display.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/ui/spice-display.c b/ui/spice-display.c
index 8a5b325..2a2a7c1 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -460,6 +460,13 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
 
     memset(&ssd->dirty, 0, sizeof(ssd->dirty));
     ssd->notify++;
+
+    qemu_mutex_lock(&ssd->lock);
+    if (ssd->cursor) {
+        g_free(ssd->ptr_define);
+        ssd->ptr_define = qemu_spice_create_cursor_update(ssd, ssd->cursor, 0);
+    }
+    qemu_mutex_unlock(&ssd->lock);
 }
 
 static void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
@@ -467,8 +474,6 @@ static void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
     if (ssd->cursor) {
         assert(ssd->dcl.con);
         dpy_cursor_define(ssd->dcl.con, ssd->cursor);
-        cursor_put(ssd->cursor);
-        ssd->cursor = NULL;
     }
     if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
         assert(ssd->dcl.con);
@@ -750,6 +755,11 @@ static void display_mouse_define(DisplayChangeListener *dcl,
     SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
 
     qemu_mutex_lock(&ssd->lock);
+    if (c) {
+        cursor_get(c);
+    }
+    cursor_put(ssd->cursor);
+    ssd->cursor = c;
     ssd->hot_x = c->hot_x;
     ssd->hot_y = c->hot_y;
     g_free(ssd->ptr_move);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 4/8] spice: reset cursor on resize Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18 12:30   ` Marc-André Lureau
  2016-02-18 16:30   ` Eric Blake
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 6/8] spice: tweak debug messages Gerd Hoffmann
                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

This adds support for dma-buf passing to spice.  This makes virtio-gpu
with 3d acceleration work with spice.

Workflow:
 * virglrenderer renders the guest command stream into a texture.
 * qemu exports the texture as dma-buf and passes on that dma-buf
   to spice-server.
 * spice-server passes the dma-buf to spice-client, using unix
   socket file descriptor passing.
 * spice-client asks the window systems composer to render the
   dma-buf to the screen.

Requires cutting edge spice (server) and spice-gtk (client) builds,
from git master branch.

Also requires libvirt managing your qemu instance, and using
"virt-viewer --attach $guest".  libvirt will connect spice-server and
spice-client using unix sockets instead of tcp sockets then, which
is required for file descriptor passing.

Works for the local case (spice server and client on the same machine)
only.  Supporting remote too is planned (by feeding the dma-bufs into
gpu-assisted video encoder), but not there yet.

gl mode is turned off by default, use "-spice gl=on,$otherargs" to
enable it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/spice-display.h |  18 +++++++
 qemu-options.hx            |   4 ++
 ui/spice-core.c            |  18 ++++++-
 ui/spice-display.c         | 129 +++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 165 insertions(+), 4 deletions(-)

diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index b25328a..5c5726a 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -23,6 +23,16 @@
 #include "ui/qemu-pixman.h"
 #include "ui/console.h"
 #include "sysemu/sysemu.h"
+#ifdef CONFIG_OPENGL_DMABUF
+#include "ui/egl-helpers.h"
+#include "ui/egl-context.h"
+#endif
+
+#if defined(CONFIG_OPENGL_DMABUF)
+# if SPICE_SERVER_VERSION >= 0x000d00 /* release 0.13.0 */
+#  define HAVE_SPICE_GL 1
+# endif
+#endif
 
 #define NUM_MEMSLOTS 8
 #define MEMSLOT_GENERATION_BITS 8
@@ -50,6 +60,7 @@ enum {
     QXL_COOKIE_TYPE_IO,
     QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
     QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
+    QXL_COOKIE_TYPE_GL_DRAW_DONE,
 };
 
 typedef struct QXLCookie {
@@ -104,6 +115,13 @@ struct SimpleSpiceDisplay {
     QEMUCursor *cursor;
     int mouse_x, mouse_y;
     QEMUBH *cursor_bh;
+
+#ifdef HAVE_SPICE_GL
+    /* opengl rendering */
+    QEMUBH *gl_unblock_bh;
+    QEMUTimer *gl_unblock_timer;
+    int dmabuf_fd;
+#endif
 };
 
 struct SimpleSpiceUpdate {
diff --git a/qemu-options.hx b/qemu-options.hx
index 2f0465e..8cc367e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1051,6 +1051,7 @@ DEF("spice", HAS_ARG, QEMU_OPTION_spice,
     "       [,streaming-video=[off|all|filter]][,disable-copy-paste]\n"
     "       [,disable-agent-file-xfer][,agent-mouse=[on|off]]\n"
     "       [,playback-compression=[on|off]][,seamless-migration=[on|off]]\n"
+    "       [,gl=[on|off]\n"
     "   enable spice\n"
     "   at least one of {port, tls-port} is mandatory\n",
     QEMU_ARCH_ALL)
@@ -1142,6 +1143,9 @@ Enable/disable audio stream compression (using celt 0.5.1).  Default is on.
 @item seamless-migration=[on|off]
 Enable/disable spice seamless migration. Default is off.
 
+@item gl=[on|off]
+Enable/disable OpenGL context. Default is off.
+
 @end table
 ETEXI
 
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 4dbd99a..2c9aba5 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -39,6 +39,9 @@
 #include "hw/hw.h"
 #include "ui/spice-display.h"
 #include "qapi-event.h"
+#ifdef CONFIG_OPENGL_DMABUF
+#include "ui/egl-helpers.h"
+#endif
 
 /* core bits */
 
@@ -494,9 +497,14 @@ static QemuOptsList qemu_spice_opts = {
         },{
             .name = "playback-compression",
             .type = QEMU_OPT_BOOL,
-        }, {
+        },{
             .name = "seamless-migration",
             .type = QEMU_OPT_BOOL,
+#ifdef CONFIG_OPENGL_DMABUF
+        },{
+            .name = "gl",
+            .type = QEMU_OPT_BOOL,
+#endif
         },
         { /* end of list */ }
     },
@@ -819,6 +827,14 @@ void qemu_spice_init(void)
 #if SPICE_SERVER_VERSION >= 0x000c02
     qemu_spice_register_ports();
 #endif
+
+#ifdef CONFIG_OPENGL_DMABUF
+    if (qemu_opt_get_bool(opts, "gl", 0)) {
+        if (egl_rendernode_init() == 0) {
+            display_opengl = 1;
+        }
+    }
+#endif
 }
 
 int qemu_spice_add_interface(SpiceBaseInstance *sin)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 2a2a7c1..17a71ce 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -650,9 +650,23 @@ static void interface_update_area_complete(QXLInstance *sin,
 /* called from spice server thread context only */
 static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
 {
-    /* should never be called, used in qxl native mode only */
-    fprintf(stderr, "%s: abort()\n", __func__);
-    abort();
+    QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
+
+    switch (cookie->type) {
+#ifdef HAVE_SPICE_GL
+    case QXL_COOKIE_TYPE_GL_DRAW_DONE:
+    {
+        SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+        qemu_bh_schedule(ssd->gl_unblock_bh);
+        break;
+    }
+#endif
+    default:
+        /* should never be called, used in qxl native mode only */
+        fprintf(stderr, "%s: abort()\n", __func__);
+        abort();
+    }
+    g_free(cookie);
 }
 
 static void interface_set_client_capabilities(QXLInstance *sin,
@@ -779,6 +793,106 @@ static const DisplayChangeListenerOps display_listener_ops = {
     .dpy_cursor_define    = display_mouse_define,
 };
 
+#ifdef HAVE_SPICE_GL
+
+static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd, bool block)
+{
+    uint64_t timeout;
+
+    if (block) {
+        timeout = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+        timeout += 1000; /* one sec */
+        timer_mod(ssd->gl_unblock_timer, timeout);
+    } else {
+        timer_del(ssd->gl_unblock_timer);
+    }
+    graphic_hw_gl_block(ssd->dcl.con, block);
+}
+
+static void qemu_spice_gl_unblock_bh(void *opaque)
+{
+    SimpleSpiceDisplay *ssd = opaque;
+
+    qemu_spice_gl_block(ssd, false);
+}
+
+static void qemu_spice_gl_block_timer(void *opaque)
+{
+    fprintf(stderr, "WARNING: spice: no gl-draw-done within one second\n");
+}
+
+static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
+                                                  QEMUGLParams *params)
+{
+    eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                   qemu_egl_rn_ctx);
+    return qemu_egl_create_context(dcl, params);
+}
+
+static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
+                                  uint32_t tex_id,
+                                  bool y_0_top,
+                                  uint32_t x, uint32_t y,
+                                  uint32_t w, uint32_t h)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    EGLint stride = 0, fourcc = 0;
+    int fd = -1;
+
+    if (tex_id) {
+        fd = egl_get_fd_for_texture(tex_id, &stride, &fourcc);
+        if (fd < 0) {
+            fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
+            return;
+        }
+    }
+    dprint(0, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
+           w, h, stride, fourcc);
+
+    assert(!tex_id || fd >= 0);
+    spice_qxl_gl_scanout(&ssd->qxl, fd,
+                         surface_width(ssd->ds),
+                         surface_height(ssd->ds),
+                         stride, fourcc, y_0_top);
+
+    if (ssd->dmabuf_fd != -1) {
+        close(ssd->dmabuf_fd);
+    }
+    ssd->dmabuf_fd = fd;
+}
+
+static void qemu_spice_gl_update(DisplayChangeListener *dcl,
+                                 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    uint64_t cookie;
+
+    dprint(1, "%s\n", __func__);
+    qemu_spice_gl_block(ssd, true);
+    cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
+    spice_qxl_gl_draw_async(&ssd->qxl, x, y, w, h, cookie);
+}
+
+static const DisplayChangeListenerOps display_listener_gl_ops = {
+    .dpy_name             = "spice-egl",
+    .dpy_gfx_update       = display_update,
+    .dpy_gfx_switch       = display_switch,
+    .dpy_gfx_check_format = qemu_pixman_check_format,
+    .dpy_refresh          = display_refresh,
+    .dpy_mouse_set        = display_mouse_set,
+    .dpy_cursor_define    = display_mouse_define,
+
+    .dpy_gl_ctx_create       = qemu_spice_gl_create_context,
+    .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
+    .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
+    .dpy_gl_ctx_get_current  = qemu_egl_get_current_context,
+
+    .dpy_gl_scanout          = qemu_spice_gl_scanout,
+    .dpy_gl_update           = qemu_spice_gl_update,
+};
+
+#endif /* HAVE_SPICE_GL */
+
 static void qemu_spice_display_init_one(QemuConsole *con)
 {
     SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
@@ -792,6 +906,15 @@ static void qemu_spice_display_init_one(QemuConsole *con)
     qemu_spice_create_host_memslot(ssd);
 
     ssd->dcl.ops = &display_listener_ops;
+#ifdef HAVE_SPICE_GL
+    if (display_opengl) {
+        ssd->dcl.ops = &display_listener_gl_ops;
+        ssd->dmabuf_fd = -1;
+        ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
+        ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
+                                             qemu_spice_gl_block_timer, ssd);
+    }
+#endif
     ssd->dcl.con = con;
     register_displaychangelistener(&ssd->dcl);
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 6/8] spice: tweak debug messages.
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 7/8] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

Adjust message levels, make messages more verbose.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-display.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/ui/spice-display.c b/ui/spice-display.c
index 17a71ce..264ecdb 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -568,7 +568,7 @@ static int interface_get_command(QXLInstance *sin, QXLCommandExt *ext)
 
 static int interface_req_cmd_notification(QXLInstance *sin)
 {
-    dprint(1, "%s/%d:\n", __func__, sin->id);
+    dprint(2, "%s/%d:\n", __func__, sin->id);
     return 1;
 }
 
@@ -621,7 +621,7 @@ static int interface_get_cursor_command(QXLInstance *sin, QXLCommandExt *ext)
 
 static int interface_req_cursor_notification(QXLInstance *sin)
 {
-    dprint(1, "%s:\n", __FUNCTION__);
+    dprint(2, "%s:\n", __func__);
     return 1;
 }
 
@@ -845,9 +845,11 @@ static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
             fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
             return;
         }
+        dprint(1, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
+               w, h, stride, fourcc);
+    } else {
+        dprint(1, "%s: no texture (no framebuffer)\n", __func__);
     }
-    dprint(0, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
-           w, h, stride, fourcc);
 
     assert(!tex_id || fd >= 0);
     spice_qxl_gl_scanout(&ssd->qxl, fd,
@@ -867,7 +869,7 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
     SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
     uint64_t cookie;
 
-    dprint(1, "%s\n", __func__);
+    dprint(2, "%s: %dx%d+%d+%d\n", __func__, w, h, x, y);
     qemu_spice_gl_block(ssd, true);
     cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
     spice_qxl_gl_draw_async(&ssd->qxl, x, y, w, h, cookie);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 7/8] spice/gl: render DisplaySurface via opengl
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 6/8] spice: tweak debug messages Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 8/8] spice/gl: create dummy primary surface (RfC) Gerd Hoffmann
  2016-02-18 12:20 ` [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Marc-André Lureau
  8 siblings, 0 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

This switches over spice (in opengl mode) to render DisplaySurface
updates into a opengl texture, using the helper functions in
ui/console-gl.c.  With this patch applied spice (with gl=on) will
stop using qxl rendering ops, it will use dma-buf passing all the
time, i.e. for bios/bootloader (before virtio-gpu driver is loaded)
too.

This should improve performance even using spice (with gl=on) with
non-accelerated stdvga because we stop squeezing all display updates
through a unix/tcp socket and basically using a shared memory transport
instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/spice-display.h |  2 ++
 ui/spice-display.c         | 81 ++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index 5c5726a..f613141 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -121,6 +121,8 @@ struct SimpleSpiceDisplay {
     QEMUBH *gl_unblock_bh;
     QEMUTimer *gl_unblock_timer;
     int dmabuf_fd;
+    ConsoleGLState *gls;
+    int gl_updates;
 #endif
 };
 
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 264ecdb..b222984 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -821,6 +821,72 @@ static void qemu_spice_gl_block_timer(void *opaque)
     fprintf(stderr, "WARNING: spice: no gl-draw-done within one second\n");
 }
 
+static void spice_gl_refresh(DisplayChangeListener *dcl)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    uint64_t cookie;
+
+    if (!ssd->ds || qemu_console_is_gl_blocked(ssd->dcl.con)) {
+        return;
+    }
+
+    graphic_hw_update(dcl->con);
+    if (ssd->gl_updates) {
+        qemu_spice_gl_block(ssd, true);
+        cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
+        spice_qxl_gl_draw_async(&ssd->qxl, 0, 0,
+                                surface_width(ssd->ds),
+                                surface_height(ssd->ds),
+                                cookie);
+        ssd->gl_updates = 0;
+    }
+}
+
+static void spice_gl_update(DisplayChangeListener *dcl,
+                            int x, int y, int w, int h)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+
+    surface_gl_update_texture(ssd->gls, ssd->ds, x, y, w, h);
+    ssd->gl_updates++;
+}
+
+static void spice_gl_switch(DisplayChangeListener *dcl,
+                            struct DisplaySurface *new_surface)
+{
+    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+    EGLint stride, fourcc;
+    int fd;
+
+    if (ssd->ds) {
+        surface_gl_destroy_texture(ssd->gls, ssd->ds);
+    }
+    ssd->ds = new_surface;
+    if (ssd->ds) {
+        surface_gl_create_texture(ssd->gls, ssd->ds);
+        fd = egl_get_fd_for_texture(ssd->ds->texture,
+                                    &stride, &fourcc);
+        if (fd < 0) {
+            surface_gl_destroy_texture(ssd->gls, ssd->ds);
+            return;
+        }
+
+        dprint(1, "%s: %dx%d (stride %d/%d, fourcc 0x%x)\n", __func__,
+               surface_width(ssd->ds), surface_height(ssd->ds),
+               surface_stride(ssd->ds), stride, fourcc);
+
+        spice_qxl_gl_scanout(&ssd->qxl, fd,
+                             surface_width(ssd->ds),
+                             surface_height(ssd->ds),
+                             stride, fourcc, false);
+
+        if (ssd->dmabuf_fd != -1) {
+            close(ssd->dmabuf_fd);
+        }
+        ssd->dmabuf_fd = fd;
+    }
+}
+
 static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
                                                   QEMUGLParams *params)
 {
@@ -876,13 +942,13 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl,
 }
 
 static const DisplayChangeListenerOps display_listener_gl_ops = {
-    .dpy_name             = "spice-egl",
-    .dpy_gfx_update       = display_update,
-    .dpy_gfx_switch       = display_switch,
-    .dpy_gfx_check_format = qemu_pixman_check_format,
-    .dpy_refresh          = display_refresh,
-    .dpy_mouse_set        = display_mouse_set,
-    .dpy_cursor_define    = display_mouse_define,
+    .dpy_name                = "spice-egl",
+    .dpy_gfx_update          = spice_gl_update,
+    .dpy_gfx_switch          = spice_gl_switch,
+    .dpy_gfx_check_format    = console_gl_check_format,
+    .dpy_refresh             = spice_gl_refresh,
+    .dpy_mouse_set           = display_mouse_set,
+    .dpy_cursor_define       = display_mouse_define,
 
     .dpy_gl_ctx_create       = qemu_spice_gl_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
@@ -915,6 +981,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)
         ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
         ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
                                              qemu_spice_gl_block_timer, ssd);
+        ssd->gls = console_gl_init_context();
     }
 #endif
     ssd->dcl.con = con;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 8/8] spice/gl: create dummy primary surface (RfC)
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 7/8] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
@ 2016-02-18  9:26 ` Gerd Hoffmann
  2016-02-18 12:20 ` [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Marc-André Lureau
  8 siblings, 0 replies; 16+ messages in thread
From: Gerd Hoffmann @ 2016-02-18  9:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: spice-devel, Marc-André Lureau, Gerd Hoffmann

Current spice client expects we create a primary surface,
even if we do display updates using dma-bufs exclusively.

So just do that to get things going.

Not fully clear whenever that is intentional or a bug on
the spice side, so I keep this as separate patch for now.

I think this should either be squashed into the previous
patch, or dropped after fixing things on the spice side.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/spice-display.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/ui/spice-display.c b/ui/spice-display.c
index b222984..54702bb 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -856,13 +856,27 @@ static void spice_gl_switch(DisplayChangeListener *dcl,
 {
     SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
     EGLint stride, fourcc;
+    bool resize = true;
     int fd;
 
+    if (ssd->ds && new_surface &&
+        surface_width(ssd->ds)  == surface_width(new_surface)  &&
+        surface_height(ssd->ds) == surface_height(new_surface) &&
+        surface_format(ssd->ds) == surface_format(new_surface)) {
+        resize = false;
+    }
+
     if (ssd->ds) {
         surface_gl_destroy_texture(ssd->gls, ssd->ds);
+        if (resize) {
+            qemu_spice_destroy_host_primary(ssd);
+        }
     }
     ssd->ds = new_surface;
     if (ssd->ds) {
+        if (resize) {
+            qemu_spice_create_host_primary(ssd);
+        }
         surface_gl_create_texture(ssd->gls, ssd->ds);
         fd = egl_get_fd_for_texture(ssd->ds->texture,
                                     &stride, &fourcc);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support
  2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 8/8] spice/gl: create dummy primary surface (RfC) Gerd Hoffmann
@ 2016-02-18 12:20 ` Marc-André Lureau
  8 siblings, 0 replies; 16+ messages in thread
From: Marc-André Lureau @ 2016-02-18 12:20 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: spice-devel, QEMU

Hi

On Thu, Feb 18, 2016 at 10:26 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>   Hi,
>
> This patch series adds support for opengl and dma-buf passing to spice.
> With this in place you can use virtio-gpu in 3d (virgl) mode with spice.
> Not fully clear whenever the last patch (tagged as RfC) is actually
> needed.
>
> please review,
>   Gerd
>
> Gerd Hoffmann (7):
>   configure: add dma-buf support detection.
>   egl-helpers: add functions for render nodes and dma-buf passing
>   console: track gl_block state in QemuConsole
>   spice: add opengl/virgl/dmabuf support
>   spice: tweak debug messages.
>   spice/gl: render DisplaySurface via opengl
>   spice/gl: create dummy primary surface (RfC)
>
> Marc-André Lureau (1):
>   spice: reset cursor on resize
>

Please reorder so that "track gl_block state" is closer to what it is
actually needed for.

After "add opengl/virgl/dmabuf support", spice+virgl starts working.
I'd like to have this ready and merged before the rest of the series,
so I'll focus on that.

>  configure                  |  20 +++-
>  include/ui/console.h       |   1 +
>  include/ui/egl-helpers.h   |  13 +++
>  include/ui/spice-display.h |  20 ++++
>  qemu-options.hx            |   4 +
>  ui/console.c               |  15 ++-
>  ui/egl-helpers.c           | 129 +++++++++++++++++++++++++
>  ui/spice-core.c            |  18 +++-
>  ui/spice-display.c         | 230 +++++++++++++++++++++++++++++++++++++++++++--
>  9 files changed, 437 insertions(+), 13 deletions(-)
>
> --
> 1.8.3.1
>



-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
@ 2016-02-18 12:30   ` Marc-André Lureau
  2016-02-18 16:30   ` Eric Blake
  1 sibling, 0 replies; 16+ messages in thread
From: Marc-André Lureau @ 2016-02-18 12:30 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: spice-devel, QEMU

Hi

On Thu, Feb 18, 2016 at 10:26 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> This adds support for dma-buf passing to spice.  This makes virtio-gpu
> with 3d acceleration work with spice.
>
> Workflow:
>  * virglrenderer renders the guest command stream into a texture.
>  * qemu exports the texture as dma-buf and passes on that dma-buf
>    to spice-server.
>  * spice-server passes the dma-buf to spice-client, using unix
>    socket file descriptor passing.
>  * spice-client asks the window systems composer to render the
>    dma-buf to the screen.
>
> Requires cutting edge spice (server) and spice-gtk (client) builds,
> from git master branch.
>
> Also requires libvirt managing your qemu instance, and using
> "virt-viewer --attach $guest".  libvirt will connect spice-server and
> spice-client using unix sockets instead of tcp sockets then, which
> is required for file descriptor passing.
>
> Works for the local case (spice server and client on the same machine)
> only.  Supporting remote too is planned (by feeding the dma-bufs into
> gpu-assisted video encoder), but not there yet.
>
> gl mode is turned off by default, use "-spice gl=on,$otherargs" to
> enable it.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

I did the initial implementation of this patch, and I spent
considerable time testing and fixing yours. Even if you don't always
take my patch or fixes, I think it'd be fair adding me as Signed-off.

> ---
>  include/ui/spice-display.h |  18 +++++++
>  qemu-options.hx            |   4 ++
>  ui/spice-core.c            |  18 ++++++-
>  ui/spice-display.c         | 129 +++++++++++++++++++++++++++++++++++++++++++--
>  4 files changed, 165 insertions(+), 4 deletions(-)
>
> diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
> index b25328a..5c5726a 100644
> --- a/include/ui/spice-display.h
> +++ b/include/ui/spice-display.h
> @@ -23,6 +23,16 @@
>  #include "ui/qemu-pixman.h"
>  #include "ui/console.h"
>  #include "sysemu/sysemu.h"
> +#ifdef CONFIG_OPENGL_DMABUF
> +#include "ui/egl-helpers.h"
> +#include "ui/egl-context.h"
> +#endif
> +
> +#if defined(CONFIG_OPENGL_DMABUF)
> +# if SPICE_SERVER_VERSION >= 0x000d00 /* release 0.13.0 */

It will be most likely 0.13.1, at least not 0.13.0.

> +#  define HAVE_SPICE_GL 1
> +# endif
> +#endif
>
>  #define NUM_MEMSLOTS 8
>  #define MEMSLOT_GENERATION_BITS 8
> @@ -50,6 +60,7 @@ enum {
>      QXL_COOKIE_TYPE_IO,
>      QXL_COOKIE_TYPE_RENDER_UPDATE_AREA,
>      QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
> +    QXL_COOKIE_TYPE_GL_DRAW_DONE,
>  };
>
>  typedef struct QXLCookie {
> @@ -104,6 +115,13 @@ struct SimpleSpiceDisplay {
>      QEMUCursor *cursor;
>      int mouse_x, mouse_y;
>      QEMUBH *cursor_bh;
> +
> +#ifdef HAVE_SPICE_GL
> +    /* opengl rendering */
> +    QEMUBH *gl_unblock_bh;
> +    QEMUTimer *gl_unblock_timer;

I think it would make sense if this helper timer would be a seperate
patch (we may want to revert or change it). It would make the patch
easier to read.

> +    int dmabuf_fd;
> +#endif
>  };
>
>  struct SimpleSpiceUpdate {
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 2f0465e..8cc367e 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1051,6 +1051,7 @@ DEF("spice", HAS_ARG, QEMU_OPTION_spice,
>      "       [,streaming-video=[off|all|filter]][,disable-copy-paste]\n"
>      "       [,disable-agent-file-xfer][,agent-mouse=[on|off]]\n"
>      "       [,playback-compression=[on|off]][,seamless-migration=[on|off]]\n"
> +    "       [,gl=[on|off]\n"

missing ]

>      "   enable spice\n"
>      "   at least one of {port, tls-port} is mandatory\n",
>      QEMU_ARCH_ALL)
> @@ -1142,6 +1143,9 @@ Enable/disable audio stream compression (using celt 0.5.1).  Default is on.
>  @item seamless-migration=[on|off]
>  Enable/disable spice seamless migration. Default is off.
>
> +@item gl=[on|off]
> +Enable/disable OpenGL context. Default is off.
> +
>  @end table
>  ETEXI
>
> diff --git a/ui/spice-core.c b/ui/spice-core.c
> index 4dbd99a..2c9aba5 100644
> --- a/ui/spice-core.c
> +++ b/ui/spice-core.c
> @@ -39,6 +39,9 @@
>  #include "hw/hw.h"
>  #include "ui/spice-display.h"
>  #include "qapi-event.h"
> +#ifdef CONFIG_OPENGL_DMABUF

we may want to use HAVE_SPICE_GL to simplify things (what can we
expect with dmabuf && !spice-gl here?)

> +#include "ui/egl-helpers.h"
> +#endif
>
>  /* core bits */
>
> @@ -494,9 +497,14 @@ static QemuOptsList qemu_spice_opts = {
>          },{
>              .name = "playback-compression",
>              .type = QEMU_OPT_BOOL,
> -        }, {
> +        },{
>              .name = "seamless-migration",
>              .type = QEMU_OPT_BOOL,
> +#ifdef CONFIG_OPENGL_DMABUF
> +        },{
> +            .name = "gl",
> +            .type = QEMU_OPT_BOOL,
> +#endif
>          },
>          { /* end of list */ }
>      },
> @@ -819,6 +827,14 @@ void qemu_spice_init(void)
>  #if SPICE_SERVER_VERSION >= 0x000c02
>      qemu_spice_register_ports();
>  #endif
> +
> +#ifdef CONFIG_OPENGL_DMABUF
> +    if (qemu_opt_get_bool(opts, "gl", 0)) {
> +        if (egl_rendernode_init() == 0) {
> +            display_opengl = 1;
> +        }
> +    }
> +#endif
>  }
>
>  int qemu_spice_add_interface(SpiceBaseInstance *sin)
> diff --git a/ui/spice-display.c b/ui/spice-display.c
> index 2a2a7c1..17a71ce 100644
> --- a/ui/spice-display.c
> +++ b/ui/spice-display.c
> @@ -650,9 +650,23 @@ static void interface_update_area_complete(QXLInstance *sin,
>  /* called from spice server thread context only */
>  static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
>  {
> -    /* should never be called, used in qxl native mode only */
> -    fprintf(stderr, "%s: abort()\n", __func__);
> -    abort();
> +    QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
> +
> +    switch (cookie->type) {
> +#ifdef HAVE_SPICE_GL
> +    case QXL_COOKIE_TYPE_GL_DRAW_DONE:
> +    {
> +        SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
> +        qemu_bh_schedule(ssd->gl_unblock_bh);
> +        break;
> +    }
> +#endif
> +    default:
> +        /* should never be called, used in qxl native mode only */
> +        fprintf(stderr, "%s: abort()\n", __func__);
> +        abort();
> +    }
> +    g_free(cookie);
>  }
>
>  static void interface_set_client_capabilities(QXLInstance *sin,
> @@ -779,6 +793,106 @@ static const DisplayChangeListenerOps display_listener_ops = {
>      .dpy_cursor_define    = display_mouse_define,
>  };
>
> +#ifdef HAVE_SPICE_GL
> +
> +static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd, bool block)
> +{
> +    uint64_t timeout;
> +
> +    if (block) {
> +        timeout = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
> +        timeout += 1000; /* one sec */
> +        timer_mod(ssd->gl_unblock_timer, timeout);
> +    } else {
> +        timer_del(ssd->gl_unblock_timer);
> +    }
> +    graphic_hw_gl_block(ssd->dcl.con, block);
> +}
> +
> +static void qemu_spice_gl_unblock_bh(void *opaque)
> +{
> +    SimpleSpiceDisplay *ssd = opaque;
> +
> +    qemu_spice_gl_block(ssd, false);
> +}
> +
> +static void qemu_spice_gl_block_timer(void *opaque)
> +{
> +    fprintf(stderr, "WARNING: spice: no gl-draw-done within one second\n");
> +}
> +
> +static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
> +                                                  QEMUGLParams *params)
> +{
> +    eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
> +                   qemu_egl_rn_ctx);
> +    return qemu_egl_create_context(dcl, params);
> +}
> +
> +static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
> +                                  uint32_t tex_id,
> +                                  bool y_0_top,
> +                                  uint32_t x, uint32_t y,
> +                                  uint32_t w, uint32_t h)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +    EGLint stride = 0, fourcc = 0;
> +    int fd = -1;
> +
> +    if (tex_id) {
> +        fd = egl_get_fd_for_texture(tex_id, &stride, &fourcc);
> +        if (fd < 0) {
> +            fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
> +            return;
> +        }
> +    }
> +    dprint(0, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
> +           w, h, stride, fourcc);
> +
> +    assert(!tex_id || fd >= 0);
> +    spice_qxl_gl_scanout(&ssd->qxl, fd,
> +                         surface_width(ssd->ds),
> +                         surface_height(ssd->ds),
> +                         stride, fourcc, y_0_top);
> +

The server and client need to know where is the monitor within the
scanout. I am surprised you deliberately dropped the monitor config
from previous patches. It seems it's not necessary to get things
working today, but I am afraid this is not what virgl expects and it
will likely break.

> +    if (ssd->dmabuf_fd != -1) {
> +        close(ssd->dmabuf_fd);
> +    }

This is incompatible with Spice server API, it is responsible for
closing it when no longer needed or outdated (otherwise finding out
whether the fd is valid in spice server will be broken)

> +    ssd->dmabuf_fd = fd;
> +}
> +
> +static void qemu_spice_gl_update(DisplayChangeListener *dcl,
> +                                 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
> +{
> +    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
> +    uint64_t cookie;
> +
> +    dprint(1, "%s\n", __func__);
> +    qemu_spice_gl_block(ssd, true);
> +    cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
> +    spice_qxl_gl_draw_async(&ssd->qxl, x, y, w, h, cookie);
> +}
> +
> +static const DisplayChangeListenerOps display_listener_gl_ops = {
> +    .dpy_name             = "spice-egl",
> +    .dpy_gfx_update       = display_update,
> +    .dpy_gfx_switch       = display_switch,
> +    .dpy_gfx_check_format = qemu_pixman_check_format,
> +    .dpy_refresh          = display_refresh,
> +    .dpy_mouse_set        = display_mouse_set,
> +    .dpy_cursor_define    = display_mouse_define,
> +
> +    .dpy_gl_ctx_create       = qemu_spice_gl_create_context,
> +    .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
> +    .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
> +    .dpy_gl_ctx_get_current  = qemu_egl_get_current_context,
> +
> +    .dpy_gl_scanout          = qemu_spice_gl_scanout,
> +    .dpy_gl_update           = qemu_spice_gl_update,
> +};
> +
> +#endif /* HAVE_SPICE_GL */
> +
>  static void qemu_spice_display_init_one(QemuConsole *con)
>  {
>      SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
> @@ -792,6 +906,15 @@ static void qemu_spice_display_init_one(QemuConsole *con)
>      qemu_spice_create_host_memslot(ssd);
>
>      ssd->dcl.ops = &display_listener_ops;
> +#ifdef HAVE_SPICE_GL
> +    if (display_opengl) {
> +        ssd->dcl.ops = &display_listener_gl_ops;
> +        ssd->dmabuf_fd = -1;
> +        ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
> +        ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
> +                                             qemu_spice_gl_block_timer, ssd);
> +    }
> +#endif
>      ssd->dcl.con = con;
>      register_displaychangelistener(&ssd->dcl);
>  }
> --
> 1.8.3.1
>

After this patch, spice+virgl works :)


-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 2/8] egl-helpers: add functions for render nodes and dma-buf passing
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 2/8] egl-helpers: add functions for render nodes and dma-buf passing Gerd Hoffmann
@ 2016-02-18 12:30   ` Marc-André Lureau
  0 siblings, 0 replies; 16+ messages in thread
From: Marc-André Lureau @ 2016-02-18 12:30 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: spice-devel, QEMU

Hi

On Thu, Feb 18, 2016 at 10:26 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> Adds helpers to open a drm render node and create a opengl
> context for it.  Also add a helper to export a texture as
> dma-buf.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  include/ui/egl-helpers.h |  13 +++++
>  ui/egl-helpers.c         | 129 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 142 insertions(+)
>
> diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
> index 8c84398..03fcf4b 100644
> --- a/include/ui/egl-helpers.h
> +++ b/include/ui/egl-helpers.h
> @@ -3,10 +3,23 @@
>
>  #include <epoxy/gl.h>
>  #include <epoxy/egl.h>
> +#include <gbm.h>
>
>  extern EGLDisplay *qemu_egl_display;
>  extern EGLConfig qemu_egl_config;
>
> +#ifdef CONFIG_OPENGL_DMABUF
> +
> +extern int qemu_egl_rn_fd;
> +extern struct gbm_device *qemu_egl_rn_gbm_dev;
> +extern EGLContext qemu_egl_rn_ctx;
> +
> +int qemu_egl_rendernode_open(void);
> +int egl_rendernode_init(void);
> +int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc);
> +
> +#endif
> +
>  EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
>
>  int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug);
> diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
> index 4c83834..54be44c 100644
> --- a/ui/egl-helpers.c
> +++ b/ui/egl-helpers.c
> @@ -1,6 +1,8 @@
>  #include "qemu/osdep.h"
>  #include <glob.h>
> +#include <dirent.h>
>
> +#include "config-host.h"
>  #include "ui/egl-helpers.h"
>
>  EGLDisplay *qemu_egl_display;
> @@ -20,6 +22,133 @@ static int egl_debug;
>
>  /* ---------------------------------------------------------------------- */
>
> +#ifdef CONFIG_OPENGL_DMABUF
> +
> +int qemu_egl_rn_fd;
> +struct gbm_device *qemu_egl_rn_gbm_dev;
> +EGLContext qemu_egl_rn_ctx;
> +
> +int qemu_egl_rendernode_open(void)
> +{
> +    DIR *dir;
> +    struct dirent *e;
> +    int r, fd;
> +    char *p;
> +
> +    dir = opendir("/dev/dri");
> +    if (!dir) {
> +        return -1;
> +    }
> +
> +    fd = -1;
> +    while ((e = readdir(dir))) {
> +        if (e->d_type != DT_CHR) {
> +            continue;
> +        }
> +
> +        if (strncmp(e->d_name, "renderD", 7)) {
> +            continue;
> +        }
> +
> +        r = asprintf(&p, "/dev/dri/%s", e->d_name);
> +        if (r < 0) {
> +            return -1;
> +        }
> +
> +        r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
> +        if (r < 0) {
> +            free(p);
> +            continue;
> +        }
> +        fd = r;
> +        free(p);
> +        break;
> +    }
> +
> +    closedir(dir);
> +    if (fd < 0) {
> +        return -1;
> +    }
> +    return fd;
> +}
> +
> +int egl_rendernode_init(void)
> +{
> +    qemu_egl_rn_fd = -1;
> +
> +    qemu_egl_rn_fd = qemu_egl_rendernode_open();
> +    if (qemu_egl_rn_fd == -1) {
> +        fprintf(stderr, "egl: no drm render node available\n");
> +        goto err;
> +    }
> +
> +    qemu_egl_rn_gbm_dev = gbm_create_device(qemu_egl_rn_fd);
> +    if (!qemu_egl_rn_gbm_dev) {
> +        fprintf(stderr, "egl: gbm_create_device failed\n");
> +        goto err;
> +    }
> +
> +    qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev, false, false);
> +
> +    if (!epoxy_has_egl_extension(qemu_egl_display,
> +                                 "EGL_KHR_surfaceless_context")) {
> +        fprintf(stderr, "egl: EGL_KHR_surfaceless_context not supported\n");
> +        goto err;
> +    }
> +    if (!epoxy_has_egl_extension(qemu_egl_display,
> +                                 "EGL_MESA_image_dma_buf_export")) {
> +        fprintf(stderr, "egl: EGL_MESA_image_dma_buf_export not supported\n");
> +        goto err;
> +    }
> +
> +    qemu_egl_rn_ctx = qemu_egl_init_ctx();
> +    if (!qemu_egl_rn_ctx) {
> +        fprintf(stderr, "egl: egl_init_ctx failed\n");
> +        goto err;
> +    }
> +
> +    return 0;
> +
> +err:
> +    if (qemu_egl_rn_gbm_dev) {
> +        gbm_device_destroy(qemu_egl_rn_gbm_dev);
> +    }
> +    if (qemu_egl_rn_fd != -1) {
> +        close(qemu_egl_rn_fd);
> +    }
> +
> +    return -1;
> +}
> +
> +int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc)
> +{
> +    EGLImageKHR image;
> +    EGLint num_planes, fd;
> +
> +    image = eglCreateImageKHR(qemu_egl_display, eglGetCurrentContext(),
> +                              EGL_GL_TEXTURE_2D_KHR,
> +                              (EGLClientBuffer)(unsigned long)tex_id,
> +                              NULL);
> +    if (!image) {
> +        return -1;
> +    }
> +
> +    eglExportDMABUFImageQueryMESA(qemu_egl_display, image, fourcc,
> +                                  &num_planes, NULL);
> +    if (num_planes != 1) {
> +        eglDestroyImageKHR(qemu_egl_display, image);
> +        return -1;
> +    }
> +    eglExportDMABUFImageMESA(qemu_egl_display, image, &fd, stride, NULL);
> +    eglDestroyImageKHR(qemu_egl_display, image);
> +
> +    return fd;
> +}
> +
> +#endif /* CONFIG_OPENGL_DMABUF */
> +
> +/* ---------------------------------------------------------------------- */
> +
>  EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
>  {
>      EGLSurface esurface;
> --
> 1.8.3.1
>

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>



-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 3/8] console: track gl_block state in QemuConsole
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 3/8] console: track gl_block state in QemuConsole Gerd Hoffmann
@ 2016-02-18 12:30   ` Marc-André Lureau
  0 siblings, 0 replies; 16+ messages in thread
From: Marc-André Lureau @ 2016-02-18 12:30 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: spice-devel, QEMU

Hi

On Thu, Feb 18, 2016 at 10:26 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> Keep track of gl_block state (added in bba19b8 console: block rendering
> until client is done) in QemuConsole and allow to query it.  This way
> we can avoid state inconsistencies in case different code paths make use
> of this.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 1/8] configure: add dma-buf support detection.
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 1/8] configure: add dma-buf support detection Gerd Hoffmann
@ 2016-02-18 12:30   ` Marc-André Lureau
  0 siblings, 0 replies; 16+ messages in thread
From: Marc-André Lureau @ 2016-02-18 12:30 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: spice-devel, QEMU

Hi

On Thu, Feb 18, 2016 at 10:26 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> Set CONFIG_OPENGL_DMABUF in case both mesa and libepoxy are
> new enough to have support for dma-buf import/export.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  configure | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/configure b/configure
> index 0aa249b..0c0472a 100755
> --- a/configure
> +++ b/configure
> @@ -279,6 +279,7 @@ smartcard=""
>  libusb=""
>  usb_redir=""
>  opengl=""
> +opengl_dmabuf="no"
>  zlib="yes"
>  lzo=""
>  snappy=""
> @@ -3274,7 +3275,7 @@ libs_softmmu="$libs_softmmu $fdt_libs"
>  # opengl probe (for sdl2, gtk, milkymist-tmu2)
>
>  if test "$opengl" != "no" ; then
> -  opengl_pkgs="epoxy"
> +  opengl_pkgs="epoxy libdrm gbm"
>    if $pkg_config $opengl_pkgs x11; then
>      opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
>      opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
> @@ -3292,6 +3293,18 @@ if test "$opengl" != "no" ; then
>    fi
>  fi
>
> +if test "$opengl" = "yes"; then
> +  cat > $TMPC << EOF
> +#include <epoxy/egl.h>
> +#ifndef EGL_MESA_image_dma_buf_export
> +# error mesa/epoxy lacks support for dmabufs (mesa 10.6+)
> +#endif
> +int main(void) { return 0; }
> +EOF
> +  if compile_prog "" "" ; then
> +    opengl_dmabuf=yes
> +  fi
> +fi
>
>  ##########################################
>  # archipelago probe
> @@ -4752,6 +4765,7 @@ echo "smartcard support $smartcard"
>  echo "libusb            $libusb"
>  echo "usb net redir     $usb_redir"
>  echo "OpenGL support    $opengl"
> +echo "OpenGL dmabufs    $opengl_dmabuf"
>  echo "libiscsi support  $libiscsi"
>  echo "libnfs support    $libnfs"
>  echo "build guest agent $guest_agent"
> @@ -5050,6 +5064,7 @@ if test "$gtk" = "yes" ; then
>    echo "CONFIG_GTK=y" >> $config_host_mak
>    echo "CONFIG_GTKABI=$gtkabi" >> $config_host_mak
>    echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak
> +  echo "GTK_LIBS=$gtk_libs" >> $config_host_mak

This could be seperated

>    if test "$gtk_gl" = "yes" ; then
>      echo "CONFIG_GTK_GL=y" >> $config_host_mak
>    fi
> @@ -5158,6 +5173,9 @@ if test "$opengl" = "yes" ; then
>    echo "CONFIG_OPENGL=y" >> $config_host_mak
>    echo "OPENGL_CFLAGS=$opengl_cflags" >> $config_host_mak
>    echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak
> +  if test "$opengl_dmabuf" = "yes" ; then
> +    echo "CONFIG_OPENGL_DMABUF=y" >> $config_host_mak
> +  fi
>  fi
>
>  if test "$lzo" = "yes" ; then
> --
> 1.8.3.1
>

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>





-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support
  2016-02-18  9:26 ` [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
  2016-02-18 12:30   ` Marc-André Lureau
@ 2016-02-18 16:30   ` Eric Blake
  2016-02-18 16:55     ` Marc-André Lureau
  1 sibling, 1 reply; 16+ messages in thread
From: Eric Blake @ 2016-02-18 16:30 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel; +Cc: spice-devel, Marc-André Lureau

[-- Attachment #1: Type: text/plain, Size: 972 bytes --]

On 02/18/2016 02:26 AM, Gerd Hoffmann wrote:
> This adds support for dma-buf passing to spice.  This makes virtio-gpu
> with 3d acceleration work with spice.
> 

> 
> gl mode is turned off by default, use "-spice gl=on,$otherargs" to
> enable it.
> 

>  
> @@ -494,9 +497,14 @@ static QemuOptsList qemu_spice_opts = {
>          },{
>              .name = "playback-compression",
>              .type = QEMU_OPT_BOOL,
> -        }, {
> +        },{
>              .name = "seamless-migration",
>              .type = QEMU_OPT_BOOL,
> +#ifdef CONFIG_OPENGL_DMABUF
> +        },{
> +            .name = "gl",
> +            .type = QEMU_OPT_BOOL,
> +#endif
>          },

How introspectible is this? Does QMP 'query-command-line-options' cope
will with showing 'gl' as an option only for the qemu binaries where the
#ifdef succeeded?

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support
  2016-02-18 16:30   ` Eric Blake
@ 2016-02-18 16:55     ` Marc-André Lureau
  0 siblings, 0 replies; 16+ messages in thread
From: Marc-André Lureau @ 2016-02-18 16:55 UTC (permalink / raw)
  To: Eric Blake; +Cc: spice-devel, Gerd Hoffmann, QEMU

Hi

On Thu, Feb 18, 2016 at 5:30 PM, Eric Blake <eblake@redhat.com> wrote:
> On 02/18/2016 02:26 AM, Gerd Hoffmann wrote:
>> This adds support for dma-buf passing to spice.  This makes virtio-gpu
>> with 3d acceleration work with spice.
>>
>
>>
>> gl mode is turned off by default, use "-spice gl=on,$otherargs" to
>> enable it.
>>
>
>>
>> @@ -494,9 +497,14 @@ static QemuOptsList qemu_spice_opts = {
>>          },{
>>              .name = "playback-compression",
>>              .type = QEMU_OPT_BOOL,
>> -        }, {
>> +        },{
>>              .name = "seamless-migration",
>>              .type = QEMU_OPT_BOOL,
>> +#ifdef CONFIG_OPENGL_DMABUF
>> +        },{
>> +            .name = "gl",
>> +            .type = QEMU_OPT_BOOL,
>> +#endif
>>          },
>
> How introspectible is this? Does QMP 'query-command-line-options' cope
> will with showing 'gl' as an option only for the qemu binaries where the
> #ifdef succeeded?

{ "execute": "query-command-line-options", "arguments": { "option": "spice" } }
{"return": [{"parameters": [{"name": "gl", "type": "boolean"},

(I just sent a libvirt patch that queries successfully the capability too)

-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-02-18 16:55 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-18  9:26 [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
2016-02-18  9:26 ` [Qemu-devel] [PATCH 1/8] configure: add dma-buf support detection Gerd Hoffmann
2016-02-18 12:30   ` Marc-André Lureau
2016-02-18  9:26 ` [Qemu-devel] [PATCH 2/8] egl-helpers: add functions for render nodes and dma-buf passing Gerd Hoffmann
2016-02-18 12:30   ` Marc-André Lureau
2016-02-18  9:26 ` [Qemu-devel] [PATCH 3/8] console: track gl_block state in QemuConsole Gerd Hoffmann
2016-02-18 12:30   ` Marc-André Lureau
2016-02-18  9:26 ` [Qemu-devel] [PATCH 4/8] spice: reset cursor on resize Gerd Hoffmann
2016-02-18  9:26 ` [Qemu-devel] [PATCH 5/8] spice: add opengl/virgl/dmabuf support Gerd Hoffmann
2016-02-18 12:30   ` Marc-André Lureau
2016-02-18 16:30   ` Eric Blake
2016-02-18 16:55     ` Marc-André Lureau
2016-02-18  9:26 ` [Qemu-devel] [PATCH 6/8] spice: tweak debug messages Gerd Hoffmann
2016-02-18  9:26 ` [Qemu-devel] [PATCH 7/8] spice/gl: render DisplaySurface via opengl Gerd Hoffmann
2016-02-18  9:26 ` [Qemu-devel] [PATCH 8/8] spice/gl: create dummy primary surface (RfC) Gerd Hoffmann
2016-02-18 12:20 ` [Qemu-devel] [PATCH 0/8] spice: add opengl/virgl/dmabuf support Marc-André Lureau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.