diff mbox series

[v3,3/5] ui: Create sync objects and fences only for blobs

Message ID 20210621192425.1188442-4-vivek.kasireddy@intel.com (mailing list archive)
State New, archived
Headers show
Series virtio-gpu: Add a default synchronization mechanism for blobs | expand

Commit Message

Kasireddy, Vivek June 21, 2021, 7:24 p.m. UTC
Create sync objects and fences only for dmabufs that are blobs. Once a
fence is created (after glFlush) and is signalled,
graphic_hw_gl_flushed() will be called and virtio-gpu cmd processing
will be resumed.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu-udmabuf.c |  1 +
 include/ui/console.h            |  1 +
 include/ui/egl-helpers.h        |  1 +
 include/ui/gtk.h                |  1 +
 ui/gtk-egl.c                    | 20 ++++++++++++++++++++
 ui/gtk-gl-area.c                | 20 ++++++++++++++++++++
 ui/gtk.c                        | 13 +++++++++++++
 7 files changed, 57 insertions(+)

Comments

Gerd Hoffmann June 23, 2021, 8:15 a.m. UTC | #1
Hi,

>      dmabuf->buf.fd = res->dmabuf_fd;
> +    dmabuf->buf.blob = true;

Do you actually need the 'blob' field?
I think checking 'fd' instead should work too.

take care,
  Gerd
Kasireddy, Vivek June 23, 2021, 7:11 p.m. UTC | #2
Hi Gerd,

>   Hi,
> 
> >      dmabuf->buf.fd = res->dmabuf_fd;
> > +    dmabuf->buf.blob = true;
> 
> Do you actually need the 'blob' field?
> I think checking 'fd' instead should work too.
[Kasireddy, Vivek] I want these changes to be limited to blob resources only as I do not
know how they might affect other use-cases or whether they are needed there or not. I
don't think I can rely on fd as vfio/display.c also populates the fd field:
    dmabuf = g_new0(VFIODMABuf, 1);
    dmabuf->dmabuf_id  = plane.dmabuf_id;
    dmabuf->buf.width  = plane.width;
    dmabuf->buf.height = plane.height;
    dmabuf->buf.stride = plane.stride;
    dmabuf->buf.fourcc = plane.drm_format;
    dmabuf->buf.modifier = plane.drm_format_mod;
    dmabuf->buf.fd     = fd;

Therefore, I need a way to identify a dmabuf that is associated with blobs vs others.

Thanks,
Vivek
Gerd Hoffmann June 24, 2021, 8:39 a.m. UTC | #3
> >   Hi,
> > 
> > >      dmabuf->buf.fd = res->dmabuf_fd;
> > > +    dmabuf->buf.blob = true;
> > 
> > Do you actually need the 'blob' field?
> > I think checking 'fd' instead should work too.
> [Kasireddy, Vivek] I want these changes to be limited to blob resources only as I do not
> know how they might affect other use-cases or whether they are needed there or not. I
> don't think I can rely on fd as vfio/display.c also populates the fd field:
>     dmabuf = g_new0(VFIODMABuf, 1);
>     dmabuf->dmabuf_id  = plane.dmabuf_id;
>     dmabuf->buf.width  = plane.width;
>     dmabuf->buf.height = plane.height;
>     dmabuf->buf.stride = plane.stride;
>     dmabuf->buf.fourcc = plane.drm_format;
>     dmabuf->buf.modifier = plane.drm_format_mod;
>     dmabuf->buf.fd     = fd;
> 
> Therefore, I need a way to identify a dmabuf that is associated with blobs vs others.

And it actually is a dma-buf too (the guest display provided by i915 gvt
mdev driver).  So fencing that should work, right?

Even if we have to restrict it to some kinds of dma-bufs the field
should have a more descriptive name like "allow_fences".

take care,
  Gerd
Kasireddy, Vivek June 24, 2021, 6:34 p.m. UTC | #4
Hi Gerd,

> > >
> > > >      dmabuf->buf.fd = res->dmabuf_fd;
> > > > +    dmabuf->buf.blob = true;
> > >
> > > Do you actually need the 'blob' field?
> > > I think checking 'fd' instead should work too.
> > [Kasireddy, Vivek] I want these changes to be limited to blob resources only as I do not
> > know how they might affect other use-cases or whether they are needed there or not. I
> > don't think I can rely on fd as vfio/display.c also populates the fd field:
> >     dmabuf = g_new0(VFIODMABuf, 1);
> >     dmabuf->dmabuf_id  = plane.dmabuf_id;
> >     dmabuf->buf.width  = plane.width;
> >     dmabuf->buf.height = plane.height;
> >     dmabuf->buf.stride = plane.stride;
> >     dmabuf->buf.fourcc = plane.drm_format;
> >     dmabuf->buf.modifier = plane.drm_format_mod;
> >     dmabuf->buf.fd     = fd;
> >
> > Therefore, I need a way to identify a dmabuf that is associated with blobs vs others.
> 
> And it actually is a dma-buf too (the guest display provided by i915 gvt
> mdev driver).  So fencing that should work, right?
[Kasireddy, Vivek] Well, for virtio-gpu, as you know we are adding a dma fence to
resource_flush to make it wait until it gets signalled by Qemu. We might have to do
to something similar on i915 GVT side but I do not have the hardware to write a patch
and test it out -- as i915 GVT is not supported for > Gen 9 platforms.

> 
> Even if we have to restrict it to some kinds of dma-bufs the field
> should have a more descriptive name like "allow_fences".
[Kasireddy, Vivek] I think limiting this to blobs makes sense at the moment. If need be,
we can extend it to include dma-bufs generated by i915 GVT later. Let me send a
v4 with your suggestion to change the name.

Thanks,
Vivek
> 
> take care,
>   Gerd
diff mbox series

Patch

diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
index 3c01a415e7..632ba06cbc 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -185,6 +185,7 @@  static VGPUDMABuf
     dmabuf->buf.stride = fb->stride;
     dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
     dmabuf->buf.fd = res->dmabuf_fd;
+    dmabuf->buf.blob = true;
 
     dmabuf->scanout_id = scanout_id;
     QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
diff --git a/include/ui/console.h b/include/ui/console.h
index 49978fdae3..570d827644 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -170,6 +170,7 @@  typedef struct QemuDmaBuf {
     bool      y0_top;
     void      *sync;
     int       fence_fd;
+    bool      blob;
 } QemuDmaBuf;
 
 typedef struct DisplayState DisplayState;
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index 2c3ba92b53..2fb6e0dd6b 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -19,6 +19,7 @@  typedef struct egl_fb {
     GLuint texture;
     GLuint framebuffer;
     bool delete_texture;
+    QemuDmaBuf *dmabuf;
 } egl_fb;
 
 void egl_fb_destroy(egl_fb *fb);
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index e6cbf0507c..3e6a48b978 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -152,6 +152,7 @@  extern bool gtk_use_gl_area;
 /* ui/gtk.c */
 void gd_update_windowsize(VirtualConsole *vc);
 int gd_monitor_update_interval(GtkWidget *widget);
+void gd_hw_gl_flushed(void *vc);
 
 /* ui/gtk-egl.c */
 void gd_egl_init(VirtualConsole *vc);
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index b671181272..f530bcd940 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -12,6 +12,7 @@ 
  */
 
 #include "qemu/osdep.h"
+#include "qemu/main-loop.h"
 
 #include "trace.h"
 
@@ -63,6 +64,7 @@  void gd_egl_draw(VirtualConsole *vc)
 {
     GdkWindow *window;
     int ww, wh;
+    QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
 
     if (!vc->gfx.gls) {
         return;
@@ -94,6 +96,14 @@  void gd_egl_draw(VirtualConsole *vc)
     }
 
     glFlush();
+    if (dmabuf) {
+        egl_dmabuf_create_fence(dmabuf);
+        if (dmabuf->fence_fd > 0) {
+            qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
+            return;
+        }
+        graphic_hw_gl_block(vc->gfx.dcl.con, false);
+    }
     graphic_hw_gl_flushed(vc->gfx.dcl.con);
 }
 
@@ -209,6 +219,8 @@  void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
                            QemuDmaBuf *dmabuf)
 {
 #ifdef CONFIG_GBM
+    VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
+
     egl_dmabuf_import_texture(dmabuf);
     if (!dmabuf->texture) {
         return;
@@ -217,6 +229,10 @@  void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
     gd_egl_scanout_texture(dcl, dmabuf->texture,
                            false, dmabuf->width, dmabuf->height,
                            0, 0, dmabuf->width, dmabuf->height);
+
+    if (dmabuf->blob) {
+        vc->gfx.guest_fb.dmabuf = dmabuf;
+    }
 #endif
 }
 
@@ -281,6 +297,10 @@  void gd_egl_scanout_flush(DisplayChangeListener *dcl,
         egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top);
     }
 
+    if (vc->gfx.guest_fb.dmabuf) {
+        egl_dmabuf_create_sync(vc->gfx.guest_fb.dmabuf);
+    }
+
     eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
 }
 
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index dd5783fec7..091194789e 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -8,6 +8,7 @@ 
  */
 
 #include "qemu/osdep.h"
+#include "qemu/main-loop.h"
 
 #include "trace.h"
 
@@ -38,6 +39,7 @@  static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
 void gd_gl_area_draw(VirtualConsole *vc)
 {
     int ww, wh, y1, y2;
+    QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
 
     if (!vc->gfx.gls) {
         return;
@@ -71,7 +73,18 @@  void gd_gl_area_draw(VirtualConsole *vc)
         surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
     }
 
+    if (dmabuf) {
+        egl_dmabuf_create_sync(dmabuf);
+    }
     glFlush();
+    if (dmabuf) {
+        egl_dmabuf_create_fence(dmabuf);
+        if (dmabuf->fence_fd > 0) {
+            qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
+            return;
+        }
+        graphic_hw_gl_block(vc->gfx.dcl.con, false);
+    }
     graphic_hw_gl_flushed(vc->gfx.dcl.con);
 }
 
@@ -213,6 +226,9 @@  void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
 {
     VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
 
+    if (vc->gfx.guest_fb.dmabuf) {
+        graphic_hw_gl_block(vc->gfx.dcl.con, true);
+    }
     gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
 }
 
@@ -231,6 +247,10 @@  void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl,
     gd_gl_area_scanout_texture(dcl, dmabuf->texture,
                                false, dmabuf->width, dmabuf->height,
                                0, 0, dmabuf->width, dmabuf->height);
+
+    if (dmabuf->blob) {
+        vc->gfx.guest_fb.dmabuf = dmabuf;
+    }
 #endif
 }
 
diff --git a/ui/gtk.c b/ui/gtk.c
index 6132bab52f..ee3a084c21 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -36,6 +36,7 @@ 
 #include "qapi/qapi-commands-machine.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qemu/cutils.h"
+#include "qemu/main-loop.h"
 
 #include "ui/console.h"
 #include "ui/gtk.h"
@@ -583,6 +584,18 @@  static void gd_gl_release_dmabuf(DisplayChangeListener *dcl,
 #endif
 }
 
+void gd_hw_gl_flushed(void *vcon)
+{
+    VirtualConsole *vc = vcon;
+    QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
+
+    graphic_hw_gl_block(vc->gfx.dcl.con, false);
+    graphic_hw_gl_flushed(vc->gfx.dcl.con);
+    qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
+    close(dmabuf->fence_fd);
+    dmabuf->fence_fd = -1;
+}
+
 /** DisplayState Callbacks (opengl version) **/
 
 static const DisplayChangeListenerOps dcl_gl_area_ops = {