qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/2] virtio-gpu: splitting one extended mode guest fb into n-


From: Dongwon Kim
Subject: Re: [PATCH 1/2] virtio-gpu: splitting one extended mode guest fb into n-scanouts
Date: Tue, 20 Jul 2021 16:23:16 -0700
User-agent: Mutt/1.9.4 (2018-02-28)

On Sun, Jul 18, 2021 at 11:17:00PM -0700, Kasireddy, Vivek wrote:
> Hi DW,
> 
> > When guest is running Linux/X11 with extended multiple displays mode 
> > enabled,
> > the guest shares one scanout resource each time containing whole surface
> > rather than sharing individual display output separately. This extended 
> > frame
> > is properly splited and rendered on the corresponding scanout surfaces but
> > not in case of blob-resource (zero copy).
> > 
> > This code change lets the qemu split this one large surface data into 
> > multiple
> > in case of blob-resource as well so that each sub frame then can be blitted
> > properly to each scanout.
> > 
> > Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
> > ---
> >  hw/display/virtio-gpu-udmabuf.c | 19 +++++++++++--------
> >  hw/display/virtio-gpu.c         |  5 +++--
> >  include/hw/virtio/virtio-gpu.h  |  5 +++--
> >  include/ui/console.h            |  4 ++++
> >  stubs/virtio-gpu-udmabuf.c      |  3 ++-
> >  5 files changed, 23 insertions(+), 13 deletions(-)
> > 
> > diff --git a/hw/display/virtio-gpu-udmabuf.c 
> > b/hw/display/virtio-gpu-udmabuf.c
> > index 3c01a415e7..a64194c6de 100644
> > --- a/hw/display/virtio-gpu-udmabuf.c
> > +++ b/hw/display/virtio-gpu-udmabuf.c
> > @@ -171,7 +171,8 @@ static VGPUDMABuf
> >  *virtio_gpu_create_dmabuf(VirtIOGPU *g,
> >                            uint32_t scanout_id,
> >                            struct virtio_gpu_simple_resource *res,
> > -                          struct virtio_gpu_framebuffer *fb)
> > +                          struct virtio_gpu_framebuffer *fb,
> > +                          struct virtio_gpu_rect *r)
> >  {
> >      VGPUDMABuf *dmabuf;
> > 
> > @@ -183,6 +184,10 @@ static VGPUDMABuf
> >      dmabuf->buf.width = fb->width;
> >      dmabuf->buf.height = fb->height;
> >      dmabuf->buf.stride = fb->stride;
> > +    dmabuf->buf.x = r->x;
> > +    dmabuf->buf.y = r->y;
> > +    dmabuf->buf.scanout_width;
> > +    dmabuf->buf.scanout_height;
> [Kasireddy, Vivek] Would you not be able to use buf.width and buf.height?
> What is the difference between these and scanout_width/height?
[DW] buf.width and buf.height is the combined width/height. For example,
if guest has two 1920x1080 w/ extended display setup, buf.width = 3840
and buf.height = 1080. buf.scanout_width and buf.scanout_height are
individual display's, so they are 1920 and 1080 respectively.

> 
> >      dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
> >      dmabuf->buf.fd = res->dmabuf_fd;
> > 
> > @@ -195,24 +200,22 @@ static VGPUDMABuf
> >  int virtio_gpu_update_dmabuf(VirtIOGPU *g,
> >                               uint32_t scanout_id,
> >                               struct virtio_gpu_simple_resource *res,
> > -                             struct virtio_gpu_framebuffer *fb)
> > +                             struct virtio_gpu_framebuffer *fb,
> > +                             struct virtio_gpu_rect *r)
> >  {
> >      struct virtio_gpu_scanout *scanout = 
> > &g->parent_obj.scanout[scanout_id];
> >      VGPUDMABuf *new_primary, *old_primary = NULL;
> > 
> > -    new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb);
> > +    new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb, r);
> >      if (!new_primary) {
> >          return -EINVAL;
> >      }
> > 
> >      if (g->dmabuf.primary) {
> > -        old_primary = g->dmabuf.primary;
> > +        old_primary = g->dmabuf.primary[scanout_id];
> >      }
> > 
> > -    g->dmabuf.primary = new_primary;
> > -    qemu_console_resize(scanout->con,
> > -                        new_primary->buf.width,
> > -                        new_primary->buf.height);
> > +    g->dmabuf.primary[scanout_id] = new_primary;
> >      dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
> > 
> >      if (old_primary) {
> > diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> > index e183f4ecda..11a87dad79 100644
> > --- a/hw/display/virtio-gpu.c
> > +++ b/hw/display/virtio-gpu.c
> > @@ -523,9 +523,9 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
> >                  console_has_gl(scanout->con)) {
> >                  dpy_gl_update(scanout->con, 0, 0, scanout->width,
> [Kasireddy, Vivek] Unrelated to your change but shouldn't 0,0 be replaced 
> with 
> scanout->x and scanout->y?
[DW] Each scanout's x and y are all 0. Actual offsets are r->s and r->y.

> 
> >                                scanout->height);
> > -                return;
> >              }
> >          }
> > +        return;
> >      }
> > 
> >      if (!res->blob &&
> > @@ -598,6 +598,7 @@ static void virtio_gpu_update_scanout(VirtIOGPU *g,
> >      scanout->y = r->y;
> >      scanout->width = r->width;
> >      scanout->height = r->height;
> > +    qemu_console_resize(scanout->con, scanout->width, scanout->height);
> [Kasireddy, Vivek] IIRC, there was no qemu_console_resize for the non-blob 
> resources case.
> Moving this call to update_scanout means that it will also be called for 
> non-blob resources
> Path; not sure if this is OK but you might want restrict this call to only 
> blob.
> 

[DW] This may not be needed for default case but I don't think it will
break anything as I see it won't do anything if the size matches. We can
limit this to blob case anyway. I will make the corresponding change in
v2.

> >  }
> > 
> >  static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
> > @@ -633,7 +634,7 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
> > 
> >      if (res->blob) {
> >          if (console_has_gl(scanout->con)) {
> > -            if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb)) {
> > +            if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb, r)) {
> [Kasireddy, Vivek] Instead of passing the rectangle "r", you might want to 
> consider using
> the scanout object which is specific to each scanout and can be easily 
> retried by:
> scanout = &g->parent_obj.scanout[scanout_id];

[DW] Again, scanout's x and y are all 0.

> 
> Thanks,
> Vivek
> >                  virtio_gpu_update_scanout(g, scanout_id, res, r);
> >                  return;
> >              }
> > diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> > index bcf54d970f..6372f4bbb5 100644
> > --- a/include/hw/virtio/virtio-gpu.h
> > +++ b/include/hw/virtio/virtio-gpu.h
> > @@ -187,7 +187,7 @@ struct VirtIOGPU {
> > 
> >      struct {
> >          QTAILQ_HEAD(, VGPUDMABuf) bufs;
> > -        VGPUDMABuf *primary;
> > +        VGPUDMABuf *primary[VIRTIO_GPU_MAX_SCANOUTS];
> >      } dmabuf;
> >  };
> > 
> > @@ -273,7 +273,8 @@ void virtio_gpu_fini_udmabuf(struct 
> > virtio_gpu_simple_resource
> > *res);
> >  int virtio_gpu_update_dmabuf(VirtIOGPU *g,
> >                               uint32_t scanout_id,
> >                               struct virtio_gpu_simple_resource *res,
> > -                             struct virtio_gpu_framebuffer *fb);
> > +                             struct virtio_gpu_framebuffer *fb,
> > +                             struct virtio_gpu_rect *r);
> > 
> >  /* virtio-gpu-3d.c */
> >  void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
> > diff --git a/include/ui/console.h b/include/ui/console.h
> > index b30b63976a..87316aef83 100644
> > --- a/include/ui/console.h
> > +++ b/include/ui/console.h
> > @@ -167,6 +167,10 @@ typedef struct QemuDmaBuf {
> >      uint32_t  fourcc;
> >      uint64_t  modifier;
> >      uint32_t  texture;
> > +    uint32_t  x;
> > +    uint32_t  y;
> > +    uint32_t  scanout_width;
> > +    uint32_t  scanout_height;
> >      bool      y0_top;
> >  } QemuDmaBuf;
> > 
> > diff --git a/stubs/virtio-gpu-udmabuf.c b/stubs/virtio-gpu-udmabuf.c
> > index 81f661441a..f692e13510 100644
> > --- a/stubs/virtio-gpu-udmabuf.c
> > +++ b/stubs/virtio-gpu-udmabuf.c
> > @@ -20,7 +20,8 @@ void virtio_gpu_fini_udmabuf(struct 
> > virtio_gpu_simple_resource
> > *res)
> >  int virtio_gpu_update_dmabuf(VirtIOGPU *g,
> >                               uint32_t scanout_id,
> >                               struct virtio_gpu_simple_resource *res,
> > -                             struct virtio_gpu_framebuffer *fb)
> > +                             struct virtio_gpu_framebuffer *fb,
> > +                             struct virtio_gpu_rect *r)
> >  {
> >      /* nothing (stub) */
> >      return 0;
> > --
> > 2.17.1
> > 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]