All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5)
@ 2021-05-19  0:14 Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 01/13] ui: Get the fd associated with udmabuf driver Vivek Kasireddy
                   ` (13 more replies)
  0 siblings, 14 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Enabling this feature would eliminate data copies from the resource
object in the Guest to the shadow resource in Qemu. This patch series
however adds support only for Blobs of type
VIRTIO_GPU_BLOB_MEM_GUEST with property VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE.

Most of the patches in this series are a rebased, refactored and bugfixed 
versions of Gerd Hoffmann's patches located here:
https://gitlab.freedesktop.org/virgl/qemu/-/commits/virtio-gpu-next

v2:
- Moved dpy_gl_update from set_scanout to resource_flush
- Dropped the modifier
- Rebase and other minor refactoring

v3:
- Rebased on top of Gerd's virgl device split series
- Split the udmabuf helpers patch from the previous 
  version into two (Gerd)
- Added explicit flush feature (last 7 patches)

v4 (Gerd):
- Dropped explicit flush feature patches from the series
- Slightly refactored udmabuf helpers patch (#3) to introduce
  and use blob and blob_size fields
- Fixed indentation issues and made other small changes in
  set_scanout_blob patch (#12)

v5:
- Rebase (only #6 - Refactor virtio_gpu_create_mapping_iov)

Cc: Gerd Hoffmann <kraxel@redhat.com>

Vivek Kasireddy (13):
  ui: Get the fd associated with udmabuf driver
  headers: Add udmabuf.h
  virtio-gpu: Add udmabuf helpers
  virtio-gpu: Add virtio_gpu_find_check_resource
  virtio-gpu: Refactor virtio_gpu_set_scanout
  virtio-gpu: Refactor virtio_gpu_create_mapping_iov
  virtio-gpu: Add initial definitions for blob resources
  virtio-gpu: Add virtio_gpu_resource_create_blob
  ui/pixman: Add qemu_pixman_to_drm_format()
  virtio-gpu: Add helpers to create and destroy dmabuf objects
  virtio-gpu: Factor out update scanout
  virtio-gpu: Add virtio_gpu_set_scanout_blob
  virtio-gpu: Update cursor data using blob

 hw/display/meson.build                   |   2 +-
 hw/display/trace-events                  |   2 +
 hw/display/virtio-gpu-base.c             |   3 +
 hw/display/virtio-gpu-udmabuf.c          | 255 +++++++++++++
 hw/display/virtio-gpu-virgl.c            |   3 +-
 hw/display/virtio-gpu.c                  | 433 ++++++++++++++++++-----
 include/hw/virtio/virtio-gpu-bswap.h     |  16 +
 include/hw/virtio/virtio-gpu.h           |  39 +-
 include/standard-headers/linux/udmabuf.h |  32 ++
 include/ui/console.h                     |   3 +
 include/ui/qemu-pixman.h                 |   1 +
 scripts/update-linux-headers.sh          |   3 +
 ui/meson.build                           |   1 +
 ui/qemu-pixman.c                         |  35 +-
 ui/udmabuf.c                             |  40 +++
 15 files changed, 758 insertions(+), 110 deletions(-)
 create mode 100644 hw/display/virtio-gpu-udmabuf.c
 create mode 100644 include/standard-headers/linux/udmabuf.h
 create mode 100644 ui/udmabuf.c

-- 
2.30.2



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

* [PATCH v5 01/13] ui: Get the fd associated with udmabuf driver
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 02/13] headers: Add udmabuf.h Vivek Kasireddy
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Try to open the udmabuf dev node for the first time or return the
fd if the device was previously opened.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 include/ui/console.h |  3 +++
 ui/meson.build       |  1 +
 ui/udmabuf.c         | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+)
 create mode 100644 ui/udmabuf.c

diff --git a/include/ui/console.h b/include/ui/console.h
index ca3c7af6a6..b30b63976a 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -471,4 +471,7 @@ bool vnc_display_reload_certs(const char *id,  Error **errp);
 /* input.c */
 int index_from_key(const char *key, size_t key_length);
 
+/* udmabuf.c */
+int udmabuf_fd(void);
+
 #endif
diff --git a/ui/meson.build b/ui/meson.build
index e8d3ff41b9..7a709ff548 100644
--- a/ui/meson.build
+++ b/ui/meson.build
@@ -11,6 +11,7 @@ softmmu_ss.add(files(
   'kbd-state.c',
   'keymaps.c',
   'qemu-pixman.c',
+  'udmabuf.c',
 ))
 softmmu_ss.add([spice_headers, files('spice-module.c')])
 
diff --git a/ui/udmabuf.c b/ui/udmabuf.c
new file mode 100644
index 0000000000..e6234fd86f
--- /dev/null
+++ b/ui/udmabuf.c
@@ -0,0 +1,40 @@
+/*
+ * udmabuf helper functions.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "ui/console.h"
+
+#ifdef CONFIG_LINUX
+
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+
+int udmabuf_fd(void)
+{
+    static bool first = true;
+    static int udmabuf;
+
+    if (!first) {
+        return udmabuf;
+    }
+    first = false;
+
+    udmabuf = open("/dev/udmabuf", O_RDWR);
+    if (udmabuf < 0) {
+        warn_report("open /dev/udmabuf: %s", strerror(errno));
+    }
+    return udmabuf;
+}
+
+#else
+
+int udmabuf_fd(void)
+{
+    return -1;
+}
+
+#endif
-- 
2.30.2



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

* [PATCH v5 02/13] headers: Add udmabuf.h
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 01/13] ui: Get the fd associated with udmabuf driver Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers Vivek Kasireddy
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

This adds udmabuf header to standard headers so that the
relevant udmabuf objects can be accessed in subsequent
patches.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 include/standard-headers/linux/udmabuf.h | 32 ++++++++++++++++++++++++
 scripts/update-linux-headers.sh          |  3 +++
 2 files changed, 35 insertions(+)
 create mode 100644 include/standard-headers/linux/udmabuf.h

diff --git a/include/standard-headers/linux/udmabuf.h b/include/standard-headers/linux/udmabuf.h
new file mode 100644
index 0000000000..e19eb5b5ce
--- /dev/null
+++ b/include/standard-headers/linux/udmabuf.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_UDMABUF_H
+#define _LINUX_UDMABUF_H
+
+#include "standard-headers/linux/types.h"
+
+#define UDMABUF_FLAGS_CLOEXEC	0x01
+
+struct udmabuf_create {
+	uint32_t memfd;
+	uint32_t flags;
+	uint64_t offset;
+	uint64_t size;
+};
+
+struct udmabuf_create_item {
+	uint32_t memfd;
+	uint32_t __pad;
+	uint64_t offset;
+	uint64_t size;
+};
+
+struct udmabuf_create_list {
+	uint32_t flags;
+	uint32_t count;
+	struct udmabuf_create_item list[];
+};
+
+#define UDMABUF_CREATE       _IOW('u', 0x42, struct udmabuf_create)
+#define UDMABUF_CREATE_LIST  _IOW('u', 0x43, struct udmabuf_create_list)
+
+#endif /* _LINUX_UDMABUF_H */
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 1050e36169..fea4d6eb65 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -34,6 +34,7 @@ cp_portable() {
     if
         grep '#include' "$f" | grep -v -e 'linux/virtio' \
                                      -e 'linux/types' \
+                                     -e 'linux/ioctl' \
                                      -e 'stdint' \
                                      -e 'linux/if_ether' \
                                      -e 'input-event-codes' \
@@ -66,6 +67,7 @@ cp_portable() {
         -e 's/__BITS_PER_LONG/HOST_LONG_BITS/' \
         -e '/\"drm.h\"/d' \
         -e '/sys\/ioctl.h/d' \
+        -e '/linux\/ioctl.h/d' \
         -e 's/SW_MAX/SW_MAX_/' \
         -e 's/atomic_t/int/' \
         -e 's/__kernel_long_t/long/' \
@@ -190,6 +192,7 @@ for i in "$tmpdir"/include/linux/*virtio*.h \
          "$tmpdir/include/linux/fuse.h" \
          "$tmpdir/include/linux/input.h" \
          "$tmpdir/include/linux/input-event-codes.h" \
+         "$tmpdir/include/linux/udmabuf.h" \
          "$tmpdir/include/linux/pci_regs.h" \
          "$tmpdir/include/linux/ethtool.h" \
          "$tmpdir/include/linux/const.h" \
-- 
2.30.2



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

* [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 01/13] ui: Get the fd associated with udmabuf driver Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 02/13] headers: Add udmabuf.h Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  6:13   ` Gerd Hoffmann
  2021-05-19  0:14 ` [PATCH v5 04/13] virtio-gpu: Add virtio_gpu_find_check_resource Vivek Kasireddy
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Add helper functions to create a dmabuf for a resource and mmap it.
Also, introduce the fields blob and blob_size so that these helpers
can start to use them but the full picture will emerge only after
adding create_blob API in patch 8 of this series.

To be able to create a dmabuf using the udmabuf driver, Qemu needs
to be lauched with the memfd memory backend like this:

qemu-system-x86_64 -m 8192m -object memory-backend-memfd,id=mem1,size=8192M
-machine memory-backend=mem1

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/meson.build          |   2 +-
 hw/display/virtio-gpu-udmabuf.c | 181 ++++++++++++++++++++++++++++++++
 include/hw/virtio/virtio-gpu.h  |  11 ++
 3 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 hw/display/virtio-gpu-udmabuf.c

diff --git a/hw/display/meson.build b/hw/display/meson.build
index aaf797c5e9..224b33f2bb 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -55,7 +55,7 @@ softmmu_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d
 if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
   virtio_gpu_ss = ss.source_set()
   virtio_gpu_ss.add(when: 'CONFIG_VIRTIO_GPU',
-                    if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c'), pixman])
+                    if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c', 'virtio-gpu-udmabuf.c'), pixman])
   virtio_gpu_ss.add(when: 'CONFIG_VHOST_USER_GPU', if_true: files('vhost-user-gpu.c'))
   hw_display_modules += {'virtio-gpu': virtio_gpu_ss}
 
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
new file mode 100644
index 0000000000..3f569ae9c8
--- /dev/null
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -0,0 +1,181 @@
+/*
+ * Virtio GPU Device
+ *
+ * Copyright Red Hat, Inc. 2013-2014
+ *
+ * Authors:
+ *     Dave Airlie <airlied@redhat.com>
+ *     Gerd Hoffmann <kraxel@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu-common.h"
+#include "qemu/iov.h"
+#include "ui/console.h"
+#include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-pixman.h"
+#include "trace.h"
+
+#ifdef CONFIG_LINUX
+
+#include "exec/ramblock.h"
+#include "sysemu/hostmem.h"
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/memfd.h>
+#include "standard-headers/linux/udmabuf.h"
+
+static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    struct udmabuf_create_list *list;
+    RAMBlock *rb;
+    ram_addr_t offset;
+    int udmabuf, i;
+
+    udmabuf = udmabuf_fd();
+    if (udmabuf < 0) {
+        return;
+    }
+
+    list = g_malloc0(sizeof(struct udmabuf_create_list) +
+                     sizeof(struct udmabuf_create_item) * res->iov_cnt);
+
+    for (i = 0; i < res->iov_cnt; i++) {
+        rcu_read_lock();
+        rb = qemu_ram_block_from_host(res->iov[i].iov_base, false, &offset);
+        rcu_read_unlock();
+
+        if (!rb || rb->fd < 0) {
+            g_free(list);
+            return;
+        }
+
+        list->list[i].memfd  = rb->fd;
+        list->list[i].offset = offset;
+        list->list[i].size   = res->iov[i].iov_len;
+    }
+
+    list->count = res->iov_cnt;
+    list->flags = UDMABUF_FLAGS_CLOEXEC;
+
+    res->dmabuf_fd = ioctl(udmabuf, UDMABUF_CREATE_LIST, list);
+    if (res->dmabuf_fd < 0) {
+        warn_report("%s: UDMABUF_CREATE_LIST: %s", __func__,
+                    strerror(errno));
+    }
+    g_free(list);
+}
+
+static void virtio_gpu_remap_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    res->remapped = mmap(NULL, res->blob_size, PROT_READ,
+                         MAP_SHARED, res->dmabuf_fd, 0);
+    if (res->remapped == MAP_FAILED) {
+        warn_report("%s: dmabuf mmap failed: %s", __func__,
+                    strerror(errno));
+        res->remapped = NULL;
+    }
+}
+
+static void virtio_gpu_destroy_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    if (res->remapped) {
+        munmap(res->remapped, res->blob_size);
+        res->remapped = NULL;
+    }
+    if (res->dmabuf_fd >= 0) {
+        close(res->dmabuf_fd);
+        res->dmabuf_fd = -1;
+    }
+}
+
+static int find_memory_backend_type(Object *obj, void *opaque)
+{
+    bool *memfd_backend = opaque;
+    int ret;
+
+    if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
+        HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+        RAMBlock *rb = backend->mr.ram_block;
+
+        if (rb && rb->fd > 0) {
+            ret = fcntl(rb->fd, F_GET_SEALS);
+            if (ret > 0) {
+                *memfd_backend = true;
+            }
+        }
+    }
+
+    return 0;
+}
+
+bool virtio_gpu_have_udmabuf(void)
+{
+    Object *memdev_root;
+    int udmabuf;
+    bool memfd_backend = false;
+
+    udmabuf = udmabuf_fd();
+    if (udmabuf < 0) {
+        return false;
+    }
+
+    memdev_root = object_resolve_path("/objects", NULL);
+    object_child_foreach(memdev_root, find_memory_backend_type, &memfd_backend);
+
+    return memfd_backend;
+}
+
+void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    void *pdata = NULL;
+
+    res->dmabuf_fd = -1;
+    if (res->iov_cnt == 1) {
+        pdata = res->iov[0].iov_base;
+    } else {
+        virtio_gpu_create_udmabuf(res);
+        if (res->dmabuf_fd < 0) {
+            return;
+        }
+        virtio_gpu_remap_udmabuf(res);
+        if (!res->remapped) {
+            return;
+        }
+        pdata = res->remapped;
+    }
+
+    res->blob = pdata;
+}
+
+void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    if (res->remapped) {
+        virtio_gpu_destroy_udmabuf(res);
+    }
+}
+
+#else
+
+bool virtio_gpu_have_udmabuf(void)
+{
+    /* nothing (stub) */
+    return false;
+}
+
+void *virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    /* nothing (stub) */
+    return NULL
+}
+
+void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
+{
+    /* nothing (stub) */
+}
+
+#endif
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 8ca2c55d9a..265b1c516c 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -50,6 +50,12 @@ struct virtio_gpu_simple_resource {
     uint32_t scanout_bitmask;
     pixman_image_t *image;
     uint64_t hostmem;
+
+    uint64_t blob_size;
+    void *blob;
+    int dmabuf_fd;
+    uint8_t *remapped;
+
     QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
 };
 
@@ -238,6 +244,11 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
                                    struct virtio_gpu_scanout *s,
                                    uint32_t resource_id);
 
+/* virtio-gpu-udmabuf.c */
+bool virtio_gpu_have_udmabuf(void);
+void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
+void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res);
+
 /* virtio-gpu-3d.c */
 void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
                                   struct virtio_gpu_ctrl_command *cmd);
-- 
2.30.2



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

* [PATCH v5 04/13] virtio-gpu: Add virtio_gpu_find_check_resource
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (2 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 05/13] virtio-gpu: Refactor virtio_gpu_set_scanout Vivek Kasireddy
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Move finding the resource and validating its backing storage into one
function.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu.c | 66 +++++++++++++++++++++++++++++------------
 1 file changed, 47 insertions(+), 19 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index db56f0454a..7b5296f0d0 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -35,6 +35,10 @@
 
 static struct virtio_gpu_simple_resource*
 virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
+static struct virtio_gpu_simple_resource *
+virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
+                               bool require_backing,
+                               const char *caller, uint32_t *error);
 
 static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
                                        struct virtio_gpu_simple_resource *res);
@@ -46,7 +50,8 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
     struct virtio_gpu_simple_resource *res;
     uint32_t pixels;
 
-    res = virtio_gpu_find_resource(g, resource_id);
+    res = virtio_gpu_find_check_resource(g, resource_id, false,
+                                         __func__, NULL);
     if (!res) {
         return;
     }
@@ -114,6 +119,37 @@ virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
     return NULL;
 }
 
+static struct virtio_gpu_simple_resource *
+virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
+                               bool require_backing,
+                               const char *caller, uint32_t *error)
+{
+    struct virtio_gpu_simple_resource *res;
+
+    res = virtio_gpu_find_resource(g, resource_id);
+    if (!res) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid resource specified %d\n",
+                      caller, resource_id);
+        if (error) {
+            *error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+        }
+        return NULL;
+    }
+
+    if (require_backing) {
+        if (!res->iov || !res->image) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
+                          caller, resource_id);
+            if (error) {
+                *error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+            }
+            return NULL;
+        }
+    }
+
+    return res;
+}
+
 void virtio_gpu_ctrl_response(VirtIOGPU *g,
                               struct virtio_gpu_ctrl_command *cmd,
                               struct virtio_gpu_ctrl_hdr *resp,
@@ -352,11 +388,9 @@ static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
     virtio_gpu_t2d_bswap(&t2d);
     trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
 
-    res = virtio_gpu_find_resource(g, t2d.resource_id);
-    if (!res || !res->iov) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, t2d.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+    res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
         return;
     }
 
@@ -410,11 +444,9 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
     trace_virtio_gpu_cmd_res_flush(rf.resource_id,
                                    rf.r.width, rf.r.height, rf.r.x, rf.r.y);
 
-    res = virtio_gpu_find_resource(g, rf.resource_id);
+    res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
+                                         __func__, &cmd->error);
     if (!res) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, rf.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
         return;
     }
 
@@ -497,11 +529,9 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
     }
 
     /* create a surface for this scanout */
-    res = virtio_gpu_find_resource(g, ss.resource_id);
+    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
+                                         __func__, &cmd->error);
     if (!res) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, ss.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
         return;
     }
 
@@ -709,11 +739,9 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g,
     virtio_gpu_bswap_32(&detach, sizeof(detach));
     trace_virtio_gpu_cmd_res_back_detach(detach.resource_id);
 
-    res = virtio_gpu_find_resource(g, detach.resource_id);
-    if (!res || !res->iov) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
-                      __func__, detach.resource_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+    res = virtio_gpu_find_check_resource(g, detach.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
         return;
     }
     virtio_gpu_cleanup_mapping(g, res);
-- 
2.30.2



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

* [PATCH v5 05/13] virtio-gpu: Refactor virtio_gpu_set_scanout
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (3 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 04/13] virtio-gpu: Add virtio_gpu_find_check_resource Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 06/13] virtio-gpu: Refactor virtio_gpu_create_mapping_iov Vivek Kasireddy
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Store the meta-data associated with a FB in a new object
(struct virtio_gpu_framebuffer) and pass the object to set_scanout.
Also move code in set_scanout into a do_set_scanout function.
This will be helpful when adding set_scanout_blob API.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu.c        | 151 +++++++++++++++++++--------------
 include/hw/virtio/virtio-gpu.h |   8 ++
 2 files changed, 95 insertions(+), 64 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7b5296f0d0..fdcedfc61e 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -500,95 +500,118 @@ static void virtio_unref_resource(pixman_image_t *image, void *data)
     pixman_image_unref(data);
 }
 
-static void virtio_gpu_set_scanout(VirtIOGPU *g,
-                                   struct virtio_gpu_ctrl_command *cmd)
+static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
+                                      uint32_t scanout_id,
+                                      struct virtio_gpu_framebuffer *fb,
+                                      struct virtio_gpu_simple_resource *res,
+                                      struct virtio_gpu_rect *r,
+                                      uint32_t *error)
 {
-    struct virtio_gpu_simple_resource *res, *ores;
+    struct virtio_gpu_simple_resource *ores;
     struct virtio_gpu_scanout *scanout;
-    pixman_format_code_t format;
-    uint32_t offset;
-    int bpp;
-    struct virtio_gpu_set_scanout ss;
+    uint8_t *data;
 
-    VIRTIO_GPU_FILL_CMD(ss);
-    virtio_gpu_bswap_32(&ss, sizeof(ss));
-    trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
-                                     ss.r.width, ss.r.height, ss.r.x, ss.r.y);
-
-    if (ss.scanout_id >= g->parent_obj.conf.max_outputs) {
+    if (scanout_id >= g->parent_obj.conf.max_outputs) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",
-                      __func__, ss.scanout_id);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
+                      __func__, scanout_id);
+        *error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
         return;
     }
-
-    g->parent_obj.enable = 1;
-    if (ss.resource_id == 0) {
-        virtio_gpu_disable_scanout(g, ss.scanout_id);
-        return;
-    }
-
-    /* create a surface for this scanout */
-    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
-                                         __func__, &cmd->error);
-    if (!res) {
-        return;
-    }
-
-    if (ss.r.x > res->width ||
-        ss.r.y > res->height ||
-        ss.r.width < 16 ||
-        ss.r.height < 16 ||
-        ss.r.width > res->width ||
-        ss.r.height > res->height ||
-        ss.r.x + ss.r.width > res->width ||
-        ss.r.y + ss.r.height > res->height) {
+    scanout = &g->parent_obj.scanout[scanout_id];
+
+    if (r->x > fb->width ||
+        r->y > fb->height ||
+        r->width < 16 ||
+        r->height < 16 ||
+        r->width > fb->width ||
+        r->height > fb->height ||
+        r->x + r->width > fb->width ||
+        r->y + r->height > fb->height) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"
-                      " resource %d, (%d,%d)+%d,%d vs %d %d\n",
-                      __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,
-                      ss.r.width, ss.r.height, res->width, res->height);
-        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+                      " resource %d, rect (%d,%d)+%d,%d, fb %d %d\n",
+                      __func__, scanout_id, res->resource_id,
+                      r->x, r->y, r->width, r->height,
+                      fb->width, fb->height);
+        *error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
         return;
     }
 
-    scanout = &g->parent_obj.scanout[ss.scanout_id];
+    g->parent_obj.enable = 1;
+    data = (uint8_t *)pixman_image_get_data(res->image);
 
-    format = pixman_image_get_format(res->image);
-    bpp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(format), 8);
-    offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);
-    if (!scanout->ds || surface_data(scanout->ds)
-        != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||
-        scanout->width != ss.r.width ||
-        scanout->height != ss.r.height) {
+    /* create a surface for this scanout */
+    if (!scanout->ds ||
+        surface_data(scanout->ds) != data + fb->offset ||
+        scanout->width != r->width ||
+        scanout->height != r->height) {
         pixman_image_t *rect;
-        void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;
-        rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,
-                                        pixman_image_get_stride(res->image));
-        pixman_image_ref(res->image);
-        pixman_image_set_destroy_function(rect, virtio_unref_resource,
-                                          res->image);
+        void *ptr = data + fb->offset;
+        rect = pixman_image_create_bits(fb->format, r->width, r->height,
+                                        ptr, fb->stride);
+
+        if (res->image) {
+            pixman_image_ref(res->image);
+            pixman_image_set_destroy_function(rect, virtio_unref_resource,
+                                              res->image);
+        }
+
         /* realloc the surface ptr */
         scanout->ds = qemu_create_displaysurface_pixman(rect);
         if (!scanout->ds) {
-            cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+            *error = VIRTIO_GPU_RESP_ERR_UNSPEC;
             return;
         }
+
         pixman_image_unref(rect);
-        dpy_gfx_replace_surface(g->parent_obj.scanout[ss.scanout_id].con,
+        dpy_gfx_replace_surface(g->parent_obj.scanout[scanout_id].con,
                                 scanout->ds);
     }
 
     ores = virtio_gpu_find_resource(g, scanout->resource_id);
     if (ores) {
-        ores->scanout_bitmask &= ~(1 << ss.scanout_id);
+        ores->scanout_bitmask &= ~(1 << scanout_id);
+    }
+
+    res->scanout_bitmask |= (1 << scanout_id);
+    scanout->resource_id = res->resource_id;
+    scanout->x = r->x;
+    scanout->y = r->y;
+    scanout->width = r->width;
+    scanout->height = r->height;
+}
+
+static void virtio_gpu_set_scanout(VirtIOGPU *g,
+                                   struct virtio_gpu_ctrl_command *cmd)
+{
+    struct virtio_gpu_simple_resource *res;
+    struct virtio_gpu_framebuffer fb = { 0 };
+    struct virtio_gpu_set_scanout ss;
+
+    VIRTIO_GPU_FILL_CMD(ss);
+    virtio_gpu_bswap_32(&ss, sizeof(ss));
+    trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,
+                                     ss.r.width, ss.r.height, ss.r.x, ss.r.y);
+
+    if (ss.resource_id == 0) {
+        virtio_gpu_disable_scanout(g, ss.scanout_id);
+        return;
     }
 
-    res->scanout_bitmask |= (1 << ss.scanout_id);
-    scanout->resource_id = ss.resource_id;
-    scanout->x = ss.r.x;
-    scanout->y = ss.r.y;
-    scanout->width = ss.r.width;
-    scanout->height = ss.r.height;
+    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
+        return;
+    }
+
+    fb.format = pixman_image_get_format(res->image);
+    fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
+    fb.width  = pixman_image_get_width(res->image);
+    fb.height = pixman_image_get_height(res->image);
+    fb.stride = pixman_image_get_stride(res->image);
+    fb.offset = ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
+
+    virtio_gpu_do_set_scanout(g, ss.scanout_id,
+                              &fb, res, &ss.r, &cmd->error);
 }
 
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 265b1c516c..b83a91a67f 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -59,6 +59,14 @@ struct virtio_gpu_simple_resource {
     QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
 };
 
+struct virtio_gpu_framebuffer {
+    pixman_format_code_t format;
+    uint32_t bytes_pp;
+    uint32_t width, height;
+    uint32_t stride;
+    uint32_t offset;
+};
+
 struct virtio_gpu_scanout {
     QemuConsole *con;
     DisplaySurface *ds;
-- 
2.30.2



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

* [PATCH v5 06/13] virtio-gpu: Refactor virtio_gpu_create_mapping_iov
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (4 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 05/13] virtio-gpu: Refactor virtio_gpu_set_scanout Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 07/13] virtio-gpu: Add initial definitions for blob resources Vivek Kasireddy
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Instead of passing the attach_backing object to extract nr_entries
and offset, explicitly pass these as arguments to this function.
This will be helpful when adding create_blob API.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu-virgl.c  |  3 ++-
 hw/display/virtio-gpu.c        | 19 +++++++++----------
 include/hw/virtio/virtio-gpu.h |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 72c14d9132..092c6dc380 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -289,7 +289,8 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
     VIRTIO_GPU_FILL_CMD(att_rb);
     trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id);
 
-    ret = virtio_gpu_create_mapping_iov(g, &att_rb, cmd, NULL, &res_iovs, &res_niov);
+    ret = virtio_gpu_create_mapping_iov(g, att_rb.nr_entries, sizeof(att_rb),
+                                        cmd, NULL, &res_iovs, &res_niov);
     if (ret != 0) {
         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
         return;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index fdcedfc61e..7a0db3a860 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -615,7 +615,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
 }
 
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
-                                  struct virtio_gpu_resource_attach_backing *ab,
+                                  uint32_t nr_entries, uint32_t offset,
                                   struct virtio_gpu_ctrl_command *cmd,
                                   uint64_t **addr, struct iovec **iov,
                                   uint32_t *niov)
@@ -624,17 +624,17 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
     size_t esize, s;
     int e, v;
 
-    if (ab->nr_entries > 16384) {
+    if (nr_entries > 16384) {
         qemu_log_mask(LOG_GUEST_ERROR,
                       "%s: nr_entries is too big (%d > 16384)\n",
-                      __func__, ab->nr_entries);
+                      __func__, nr_entries);
         return -1;
     }
 
-    esize = sizeof(*ents) * ab->nr_entries;
+    esize = sizeof(*ents) * nr_entries;
     ents = g_malloc(esize);
     s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
-                   sizeof(*ab), ents, esize);
+                   offset, ents, esize);
     if (s != esize) {
         qemu_log_mask(LOG_GUEST_ERROR,
                       "%s: command data size incorrect %zu vs %zu\n",
@@ -647,7 +647,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
     if (addr) {
         *addr = NULL;
     }
-    for (e = 0, v = 0; e < ab->nr_entries; e++) {
+    for (e = 0, v = 0; e < nr_entries; e++) {
         uint64_t a = le64_to_cpu(ents[e].addr);
         uint32_t l = le32_to_cpu(ents[e].length);
         hwaddr len;
@@ -659,8 +659,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
                                  a, &len, DMA_DIRECTION_TO_DEVICE);
             if (!map) {
                 qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
-                              " resource %d element %d\n",
-                              __func__, ab->resource_id, e);
+                              " element %d\n", __func__, e);
                 virtio_gpu_cleanup_mapping_iov(g, *iov, v);
                 g_free(ents);
                 *iov = NULL;
@@ -743,8 +742,8 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
         return;
     }
 
-    ret = virtio_gpu_create_mapping_iov(g, &ab, cmd, &res->addrs,
-                                        &res->iov, &res->iov_cnt);
+    ret = virtio_gpu_create_mapping_iov(g, ab.nr_entries, sizeof(ab), cmd,
+                                        &res->addrs, &res->iov, &res->iov_cnt);
     if (ret != 0) {
         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
         return;
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index b83a91a67f..dad9a1d221 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -238,7 +238,7 @@ void virtio_gpu_get_display_info(VirtIOGPU *g,
 void virtio_gpu_get_edid(VirtIOGPU *g,
                          struct virtio_gpu_ctrl_command *cmd);
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
-                                  struct virtio_gpu_resource_attach_backing *ab,
+                                  uint32_t nr_entries, uint32_t offset,
                                   struct virtio_gpu_ctrl_command *cmd,
                                   uint64_t **addr, struct iovec **iov,
                                   uint32_t *niov);
-- 
2.30.2



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

* [PATCH v5 07/13] virtio-gpu: Add initial definitions for blob resources
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (5 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 06/13] virtio-gpu: Refactor virtio_gpu_create_mapping_iov Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 08/13] virtio-gpu: Add virtio_gpu_resource_create_blob Vivek Kasireddy
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Add the property bit, configuration flag and other relevant
macros and definitions associated with this feature.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu-base.c   |  3 +++
 hw/display/virtio-gpu.c        | 14 ++++++++++++++
 include/hw/virtio/virtio-gpu.h |  3 +++
 3 files changed, 20 insertions(+)

diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index afb3ee7d9a..dd294276cb 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -208,6 +208,9 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t features,
     if (virtio_gpu_edid_enabled(g->conf)) {
         features |= (1 << VIRTIO_GPU_F_EDID);
     }
+    if (virtio_gpu_blob_enabled(g->conf)) {
+        features |= (1 << VIRTIO_GPU_F_RESOURCE_BLOB);
+    }
 
     return features;
 }
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7a0db3a860..f77a7fc7dd 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1108,6 +1108,18 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
     VirtIOGPU *g = VIRTIO_GPU(qdev);
 
+    if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+        if (!virtio_gpu_have_udmabuf()) {
+            error_setg(errp, "cannot enable blob resources without udmabuf");
+            return;
+        }
+
+        if (virtio_gpu_virgl_enabled(g->parent_obj.conf)) {
+            error_setg(errp, "blobs and virgl are not compatible (yet)");
+            return;
+        }
+    }
+
     if (!virtio_gpu_base_device_realize(qdev,
                                         virtio_gpu_handle_ctrl_cb,
                                         virtio_gpu_handle_cursor_cb,
@@ -1201,6 +1213,8 @@ static Property virtio_gpu_properties[] = {
     VIRTIO_GPU_BASE_PROPERTIES(VirtIOGPU, parent_obj.conf),
     DEFINE_PROP_SIZE("max_hostmem", VirtIOGPU, conf_max_hostmem,
                      256 * MiB),
+    DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
+                    VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index dad9a1d221..66e7aaad0e 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -89,6 +89,7 @@ enum virtio_gpu_base_conf_flags {
     VIRTIO_GPU_FLAG_STATS_ENABLED,
     VIRTIO_GPU_FLAG_EDID_ENABLED,
     VIRTIO_GPU_FLAG_DMABUF_ENABLED,
+    VIRTIO_GPU_FLAG_BLOB_ENABLED,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -99,6 +100,8 @@ enum virtio_gpu_base_conf_flags {
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED))
 #define virtio_gpu_dmabuf_enabled(_cfg) \
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED))
+#define virtio_gpu_blob_enabled(_cfg) \
+    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
 
 struct virtio_gpu_base_conf {
     uint32_t max_outputs;
-- 
2.30.2



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

* [PATCH v5 08/13] virtio-gpu: Add virtio_gpu_resource_create_blob
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (6 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 07/13] virtio-gpu: Add initial definitions for blob resources Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 09/13] ui/pixman: Add qemu_pixman_to_drm_format() Vivek Kasireddy
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

This API allows Qemu to register the blob allocated by the Guest
as a new resource and map its backing storage.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/trace-events              |  1 +
 hw/display/virtio-gpu.c              | 75 ++++++++++++++++++++++++++--
 include/hw/virtio/virtio-gpu-bswap.h |  9 ++++
 3 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/hw/display/trace-events b/hw/display/trace-events
index 9fccca18a1..f3f77b6984 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -32,6 +32,7 @@ virtio_gpu_cmd_get_edid(uint32_t scanout) "scanout %d"
 virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
 virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d"
 virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
+virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 0x%x, size %" PRId64
 virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f77a7fc7dd..e35c59f74f 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -137,7 +137,7 @@ virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
     }
 
     if (require_backing) {
-        if (!res->iov || !res->image) {
+        if (!res->iov || (!res->image && !res->blob)) {
             qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
                           caller, resource_id);
             if (error) {
@@ -313,6 +313,64 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
     g->hostmem += res->hostmem;
 }
 
+static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
+                                            struct virtio_gpu_ctrl_command *cmd)
+{
+    struct virtio_gpu_simple_resource *res;
+    struct virtio_gpu_resource_create_blob cblob;
+    int ret;
+
+    VIRTIO_GPU_FILL_CMD(cblob);
+    virtio_gpu_create_blob_bswap(&cblob);
+    trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
+
+    if (cblob.resource_id == 0) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+                      __func__);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+        return;
+    }
+
+    res = virtio_gpu_find_resource(g, cblob.resource_id);
+    if (res) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+                      __func__, cblob.resource_id);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+        return;
+    }
+
+    res = g_new0(struct virtio_gpu_simple_resource, 1);
+    res->resource_id = cblob.resource_id;
+    res->blob_size = cblob.size;
+
+    if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_GUEST &&
+        cblob.blob_flags != VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid memory type\n",
+                      __func__);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        g_free(res);
+        return;
+    }
+
+    if (res->iov) {
+        cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+        return;
+    }
+
+    ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
+                                        cmd, &res->addrs, &res->iov,
+                                        &res->iov_cnt);
+    if (ret != 0) {
+        cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
+        return;
+    }
+
+    res->iov_cnt = cblob.nr_entries;
+    virtio_gpu_init_udmabuf(res);
+
+    QTAILQ_INSERT_HEAD(&g->reslist, res, next);
+}
+
 static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id)
 {
     struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
@@ -390,7 +448,7 @@ static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
 
     res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
                                          __func__, &cmd->error);
-    if (!res) {
+    if (!res || res->blob) {
         return;
     }
 
@@ -446,7 +504,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
     res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
                                          __func__, &cmd->error);
-    if (!res) {
+    if (!res || res->blob) {
         return;
     }
 
@@ -715,6 +773,10 @@ static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
     res->iov_cnt = 0;
     g_free(res->addrs);
     res->addrs = NULL;
+
+    if (res->blob) {
+        virtio_gpu_fini_udmabuf(res);
+    }
 }
 
 static void
@@ -785,6 +847,13 @@ void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
     case VIRTIO_GPU_CMD_RESOURCE_CREATE_2D:
         virtio_gpu_resource_create_2d(g, cmd);
         break;
+    case VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB:
+        if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+            cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+            break;
+        }
+        virtio_gpu_resource_create_blob(g, cmd);
+        break;
     case VIRTIO_GPU_CMD_RESOURCE_UNREF:
         virtio_gpu_resource_unref(g, cmd);
         break;
diff --git a/include/hw/virtio/virtio-gpu-bswap.h b/include/hw/virtio/virtio-gpu-bswap.h
index 203f9e1718..d23ac5cc4a 100644
--- a/include/hw/virtio/virtio-gpu-bswap.h
+++ b/include/hw/virtio/virtio-gpu-bswap.h
@@ -59,4 +59,13 @@ virtio_gpu_t2d_bswap(struct virtio_gpu_transfer_to_host_2d *t2d)
     le32_to_cpus(&t2d->padding);
 }
 
+static inline void
+virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob)
+{
+    virtio_gpu_ctrl_hdr_bswap(&cblob->hdr);
+    le32_to_cpus(&cblob->resource_id);
+    le32_to_cpus(&cblob->blob_flags);
+    le64_to_cpus(&cblob->size);
+}
+
 #endif
-- 
2.30.2



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

* [PATCH v5 09/13] ui/pixman: Add qemu_pixman_to_drm_format()
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (7 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 08/13] virtio-gpu: Add virtio_gpu_resource_create_blob Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects Vivek Kasireddy
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

This new function to get the drm_format associated with a pixman
format will be useful while creating a dmabuf.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 include/ui/qemu-pixman.h |  1 +
 ui/qemu-pixman.c         | 35 ++++++++++++++++++++++++-----------
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index 87737a6f16..806ddcd7cd 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -62,6 +62,7 @@ typedef struct PixelFormat {
 PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format);
 pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian);
 pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format);
+uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman);
 int qemu_pixman_get_type(int rshift, int gshift, int bshift);
 pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
 bool qemu_pixman_check_format(DisplayChangeListener *dcl,
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 85f2945e88..3ab7e2e958 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -89,21 +89,34 @@ pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)
 }
 
 /* Note: drm is little endian, pixman is native endian */
+static const struct {
+    uint32_t drm_format;
+    pixman_format_code_t pixman_format;
+} drm_format_pixman_map[] = {
+    { DRM_FORMAT_RGB888,   PIXMAN_LE_r8g8b8   },
+    { DRM_FORMAT_ARGB8888, PIXMAN_LE_a8r8g8b8 },
+    { DRM_FORMAT_XRGB8888, PIXMAN_LE_x8r8g8b8 }
+};
+
 pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format)
 {
-    static const struct {
-        uint32_t drm_format;
-        pixman_format_code_t pixman;
-    } map[] = {
-        { DRM_FORMAT_RGB888,   PIXMAN_LE_r8g8b8   },
-        { DRM_FORMAT_ARGB8888, PIXMAN_LE_a8r8g8b8 },
-        { DRM_FORMAT_XRGB8888, PIXMAN_LE_x8r8g8b8 }
-    };
     int i;
 
-    for (i = 0; i < ARRAY_SIZE(map); i++) {
-        if (drm_format == map[i].drm_format) {
-            return map[i].pixman;
+    for (i = 0; i < ARRAY_SIZE(drm_format_pixman_map); i++) {
+        if (drm_format == drm_format_pixman_map[i].drm_format) {
+            return drm_format_pixman_map[i].pixman_format;
+        }
+    }
+    return 0;
+}
+
+uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman_format)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(drm_format_pixman_map); i++) {
+        if (pixman_format == drm_format_pixman_map[i].pixman_format) {
+            return drm_format_pixman_map[i].drm_format;
         }
     }
     return 0;
-- 
2.30.2



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

* [PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (8 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 09/13] ui/pixman: Add qemu_pixman_to_drm_format() Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  6:17   ` Gerd Hoffmann
  2021-05-19  0:14 ` [PATCH v5 11/13] virtio-gpu: Factor out update scanout Vivek Kasireddy
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

These helpers can be useful for creating dmabuf objects from blobs
and submitting them to the UI.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu-udmabuf.c | 74 +++++++++++++++++++++++++++++++++
 include/hw/virtio/virtio-gpu.h  | 15 +++++++
 2 files changed, 89 insertions(+)

diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
index 3f569ae9c8..d486419a26 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -159,6 +159,71 @@ void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
     }
 }
 
+static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf)
+{
+    struct virtio_gpu_scanout *scanout;
+
+    scanout = &g->parent_obj.scanout[dmabuf->scanout_id];
+    dpy_gl_release_dmabuf(scanout->con, &dmabuf->buf);
+    QTAILQ_REMOVE(&g->dmabuf.bufs, dmabuf, next);
+    g_free(dmabuf);
+}
+
+static VGPUDMABuf
+*virtio_gpu_create_dmabuf(VirtIOGPU *g,
+                          uint32_t scanout_id,
+                          struct virtio_gpu_simple_resource *res,
+                          struct virtio_gpu_framebuffer *fb)
+{
+    VGPUDMABuf *dmabuf;
+
+    if (res->dmabuf_fd < 0) {
+        return NULL;
+    }
+
+    dmabuf = g_new0(VGPUDMABuf, 1);
+    dmabuf->buf.width = fb->width;
+    dmabuf->buf.height = fb->height;
+    dmabuf->buf.stride = fb->stride;
+    dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
+    dmabuf->buf.fd = res->dmabuf_fd;
+
+    dmabuf->scanout_id = scanout_id;
+    QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
+
+    return dmabuf;
+}
+
+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_scanout *scanout = &g->parent_obj.scanout[scanout_id];
+    VGPUDMABuf *new_primary, *old_primary;
+
+    new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb);
+    if (!new_primary) {
+        return -EINVAL;
+    }
+
+    if (g->dmabuf.primary) {
+        old_primary = g->dmabuf.primary;
+    }
+
+    g->dmabuf.primary = new_primary;
+    qemu_console_resize(scanout->con,
+			new_primary->buf.width,
+                        new_primary->buf.height);
+    dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
+
+    if (old_primary) {
+        virtio_gpu_free_dmabuf(g, old_primary);
+    }
+
+    return 0;
+}
+
 #else
 
 bool virtio_gpu_have_udmabuf(void)
@@ -178,4 +243,13 @@ void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
     /* nothing (stub) */
 }
 
+int virtio_gpu_update_dmabuf(VirtIOGPU *g,
+                             uint32_t scanout_id,
+                             struct virtio_gpu_simple_resource *res,
+                             struct virtio_gpu_framebuffer *fb)
+{
+    /* nothing (stub) */
+    return 0;
+}
+
 #endif
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 66e7aaad0e..bcf54d970f 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -150,6 +150,12 @@ struct VirtIOGPUBaseClass {
     DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \
     DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768)
 
+typedef struct VGPUDMABuf {
+    QemuDmaBuf buf;
+    uint32_t scanout_id;
+    QTAILQ_ENTRY(VGPUDMABuf) next;
+} VGPUDMABuf;
+
 struct VirtIOGPU {
     VirtIOGPUBase parent_obj;
 
@@ -178,6 +184,11 @@ struct VirtIOGPU {
         uint32_t req_3d;
         uint32_t bytes_3d;
     } stats;
+
+    struct {
+        QTAILQ_HEAD(, VGPUDMABuf) bufs;
+        VGPUDMABuf *primary;
+    } dmabuf;
 };
 
 struct VirtIOGPUClass {
@@ -259,6 +270,10 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 bool virtio_gpu_have_udmabuf(void);
 void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
 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);
 
 /* virtio-gpu-3d.c */
 void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
-- 
2.30.2



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

* [PATCH v5 11/13] virtio-gpu: Factor out update scanout
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (9 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 12/13] virtio-gpu: Add virtio_gpu_set_scanout_blob Vivek Kasireddy
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

Creating a small helper function for updating the scanout
will be useful in the next patch where this needs to be
done early in do_set_scanout before returning.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index e35c59f74f..9118924018 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -558,6 +558,28 @@ static void virtio_unref_resource(pixman_image_t *image, void *data)
     pixman_image_unref(data);
 }
 
+static void virtio_gpu_update_scanout(VirtIOGPU *g,
+                                      uint32_t scanout_id,
+                                      struct virtio_gpu_simple_resource *res,
+                                      struct virtio_gpu_rect *r)
+{
+    struct virtio_gpu_simple_resource *ores;
+    struct virtio_gpu_scanout *scanout;
+
+    scanout = &g->parent_obj.scanout[scanout_id];
+    ores = virtio_gpu_find_resource(g, scanout->resource_id);
+    if (ores) {
+        ores->scanout_bitmask &= ~(1 << scanout_id);
+    }
+
+    res->scanout_bitmask |= (1 << scanout_id);
+    scanout->resource_id = res->resource_id;
+    scanout->x = r->x;
+    scanout->y = r->y;
+    scanout->width = r->width;
+    scanout->height = r->height;
+}
+
 static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
                                       uint32_t scanout_id,
                                       struct virtio_gpu_framebuffer *fb,
@@ -565,7 +587,6 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
                                       struct virtio_gpu_rect *r,
                                       uint32_t *error)
 {
-    struct virtio_gpu_simple_resource *ores;
     struct virtio_gpu_scanout *scanout;
     uint8_t *data;
 
@@ -625,17 +646,7 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
                                 scanout->ds);
     }
 
-    ores = virtio_gpu_find_resource(g, scanout->resource_id);
-    if (ores) {
-        ores->scanout_bitmask &= ~(1 << scanout_id);
-    }
-
-    res->scanout_bitmask |= (1 << scanout_id);
-    scanout->resource_id = res->resource_id;
-    scanout->x = r->x;
-    scanout->y = r->y;
-    scanout->width = r->width;
-    scanout->height = r->height;
+    virtio_gpu_update_scanout(g, scanout_id, res, r);
 }
 
 static void virtio_gpu_set_scanout(VirtIOGPU *g,
-- 
2.30.2



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

* [PATCH v5 12/13] virtio-gpu: Add virtio_gpu_set_scanout_blob
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (10 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 11/13] virtio-gpu: Factor out update scanout Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:14 ` [PATCH v5 13/13] virtio-gpu: Update cursor data using blob Vivek Kasireddy
  2021-05-19  0:48 ` [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) no-reply
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

This API allows Qemu to set the blob allocated by the Guest as
the scanout buffer. If Opengl support is available, then the
scanout buffer would be submitted as a dmabuf to the UI; if not,
a pixman image is created from the scanout buffer and is
submitted to the UI via the display surface.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/trace-events              |   1 +
 hw/display/virtio-gpu.c              | 102 +++++++++++++++++++++++++--
 include/hw/virtio/virtio-gpu-bswap.h |   7 ++
 3 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/hw/display/trace-events b/hw/display/trace-events
index f3f77b6984..e47264af5d 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -30,6 +30,7 @@ virtio_gpu_features(bool virgl) "virgl %d"
 virtio_gpu_cmd_get_display_info(void) ""
 virtio_gpu_cmd_get_edid(uint32_t scanout) "scanout %d"
 virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
+virtio_gpu_cmd_set_scanout_blob(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
 virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d"
 virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
 virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 0x%x, size %" PRId64
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 9118924018..8366fa2245 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -405,7 +405,7 @@ static void virtio_gpu_resource_destroy(VirtIOGPU *g,
         }
     }
 
-    pixman_image_unref(res->image);
+    qemu_pixman_image_unref(res->image);
     virtio_gpu_cleanup_mapping(g, res);
     QTAILQ_REMOVE(&g->reslist, res, next);
     g->hostmem -= res->hostmem;
@@ -494,6 +494,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 {
     struct virtio_gpu_simple_resource *res;
     struct virtio_gpu_resource_flush rf;
+    struct virtio_gpu_scanout *scanout;
     pixman_region16_t flush_region;
     int i;
 
@@ -504,16 +505,29 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
 
     res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
                                          __func__, &cmd->error);
-    if (!res || res->blob) {
+    if (!res) {
         return;
     }
 
-    if (rf.r.x > res->width ||
+    if (res->blob) {
+        for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
+            scanout = &g->parent_obj.scanout[i];
+            if (scanout->resource_id == res->resource_id &&
+                console_has_gl(scanout->con)) {
+                dpy_gl_update(scanout->con, 0, 0, scanout->width,
+                              scanout->height);
+                return;
+            }
+        }
+    }
+
+    if (!res->blob &&
+        (rf.r.x > res->width ||
         rf.r.y > res->height ||
         rf.r.width > res->width ||
         rf.r.height > res->height ||
         rf.r.x + rf.r.width > res->width ||
-        rf.r.y + rf.r.height > res->height) {
+        rf.r.y + rf.r.height > res->height)) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: flush bounds outside resource"
                       " bounds for resource %d: %d %d %d %d vs %d %d\n",
                       __func__, rf.resource_id, rf.r.x, rf.r.y,
@@ -525,7 +539,6 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
     pixman_region_init_rect(&flush_region,
                             rf.r.x, rf.r.y, rf.r.width, rf.r.height);
     for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
-        struct virtio_gpu_scanout *scanout;
         pixman_region16_t region, finalregion;
         pixman_box16_t *extents;
 
@@ -616,10 +629,23 @@ static void virtio_gpu_do_set_scanout(VirtIOGPU *g,
     }
 
     g->parent_obj.enable = 1;
-    data = (uint8_t *)pixman_image_get_data(res->image);
+
+    if (res->blob) {
+        if (console_has_gl(scanout->con)) {
+            if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb)) {
+                virtio_gpu_update_scanout(g, scanout_id, res, r);
+                return;
+            }
+        }
+
+        data = res->blob;
+    } else {
+        data = (uint8_t *)pixman_image_get_data(res->image);
+    }
 
     /* create a surface for this scanout */
-    if (!scanout->ds ||
+    if ((res->blob && !console_has_gl(scanout->con)) ||
+        !scanout->ds ||
         surface_data(scanout->ds) != data + fb->offset ||
         scanout->width != r->width ||
         scanout->height != r->height) {
@@ -683,6 +709,61 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
                               &fb, res, &ss.r, &cmd->error);
 }
 
+static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
+                                        struct virtio_gpu_ctrl_command *cmd)
+{
+    struct virtio_gpu_simple_resource *res;
+    struct virtio_gpu_framebuffer fb = { 0 };
+    struct virtio_gpu_set_scanout_blob ss;
+    uint64_t fbend;
+
+    VIRTIO_GPU_FILL_CMD(ss);
+    virtio_gpu_scanout_blob_bswap(&ss);
+    trace_virtio_gpu_cmd_set_scanout_blob(ss.scanout_id, ss.resource_id,
+                                          ss.r.width, ss.r.height, ss.r.x,
+                                          ss.r.y);
+
+    if (ss.resource_id == 0) {
+        virtio_gpu_disable_scanout(g, ss.scanout_id);
+        return;
+    }
+
+    res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
+                                         __func__, &cmd->error);
+    if (!res) {
+        return;
+    }
+
+    fb.format = virtio_gpu_get_pixman_format(ss.format);
+    if (!fb.format) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: host couldn't handle guest format %d\n",
+                      __func__, ss.format);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        return;
+    }
+
+    fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
+    fb.width = ss.width;
+    fb.height = ss.height;
+    fb.stride = ss.strides[0];
+    fb.offset = ss.offsets[0] + ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
+
+    fbend = fb.offset;
+    fbend += fb.stride * (ss.r.height - 1);
+    fbend += fb.bytes_pp * ss.r.width;
+    if (fbend > res->blob_size) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: fb end out of range\n",
+                      __func__);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        return;
+    }
+
+    virtio_gpu_do_set_scanout(g, ss.scanout_id,
+                              &fb, res, &ss.r, &cmd->error);
+}
+
 int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
                                   uint32_t nr_entries, uint32_t offset,
                                   struct virtio_gpu_ctrl_command *cmd,
@@ -877,6 +958,13 @@ void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
     case VIRTIO_GPU_CMD_SET_SCANOUT:
         virtio_gpu_set_scanout(g, cmd);
         break;
+    case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
+        if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) {
+            cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+            break;
+        }
+        virtio_gpu_set_scanout_blob(g, cmd);
+        break;
     case VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING:
         virtio_gpu_resource_attach_backing(g, cmd);
         break;
diff --git a/include/hw/virtio/virtio-gpu-bswap.h b/include/hw/virtio/virtio-gpu-bswap.h
index d23ac5cc4a..e2bee8f595 100644
--- a/include/hw/virtio/virtio-gpu-bswap.h
+++ b/include/hw/virtio/virtio-gpu-bswap.h
@@ -68,4 +68,11 @@ virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob)
     le64_to_cpus(&cblob->size);
 }
 
+static inline void
+virtio_gpu_scanout_blob_bswap(struct virtio_gpu_set_scanout_blob *ssb)
+{
+    virtio_gpu_bswap_32(ssb, sizeof(*ssb) - sizeof(ssb->offsets[3]));
+    le32_to_cpus(&ssb->offsets[3]);
+}
+
 #endif
-- 
2.30.2



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

* [PATCH v5 13/13] virtio-gpu: Update cursor data using blob
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (11 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 12/13] virtio-gpu: Add virtio_gpu_set_scanout_blob Vivek Kasireddy
@ 2021-05-19  0:14 ` Vivek Kasireddy
  2021-05-19  0:48 ` [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) no-reply
  13 siblings, 0 replies; 21+ messages in thread
From: Vivek Kasireddy @ 2021-05-19  0:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: Vivek Kasireddy, Gerd Hoffmann

If a blob is available for the cursor, copy the data from the blob.

Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
 hw/display/virtio-gpu.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 8366fa2245..d840fc195b 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -49,6 +49,7 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
 {
     struct virtio_gpu_simple_resource *res;
     uint32_t pixels;
+    void *data;
 
     res = virtio_gpu_find_check_resource(g, resource_id, false,
                                          __func__, NULL);
@@ -56,14 +57,22 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
         return;
     }
 
-    if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
-        pixman_image_get_height(res->image) != s->current_cursor->height) {
-        return;
+    if (res->blob_size) {
+        if (res->blob_size < (s->current_cursor->width *
+                              s->current_cursor->height * 4)) {
+            return;
+        }
+        data = res->blob;
+    } else {
+        if (pixman_image_get_width(res->image)  != s->current_cursor->width ||
+            pixman_image_get_height(res->image) != s->current_cursor->height) {
+            return;
+        }
+        data = pixman_image_get_data(res->image);
     }
 
     pixels = s->current_cursor->width * s->current_cursor->height;
-    memcpy(s->current_cursor->data,
-           pixman_image_get_data(res->image),
+    memcpy(s->current_cursor->data, data,
            pixels * sizeof(uint32_t));
 }
 
-- 
2.30.2



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

* Re: [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5)
  2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
                   ` (12 preceding siblings ...)
  2021-05-19  0:14 ` [PATCH v5 13/13] virtio-gpu: Update cursor data using blob Vivek Kasireddy
@ 2021-05-19  0:48 ` no-reply
  13 siblings, 0 replies; 21+ messages in thread
From: no-reply @ 2021-05-19  0:48 UTC (permalink / raw)
  To: vivek.kasireddy; +Cc: kraxel, qemu-devel, vivek.kasireddy

Patchew URL: https://patchew.org/QEMU/20210519001414.786439-1-vivek.kasireddy@intel.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210519001414.786439-1-vivek.kasireddy@intel.com
Subject: [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5)

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/20210519001414.786439-1-vivek.kasireddy@intel.com -> patchew/20210519001414.786439-1-vivek.kasireddy@intel.com
Switched to a new branch 'test'
128a9d2 virtio-gpu: Update cursor data using blob
05f9981 virtio-gpu: Add virtio_gpu_set_scanout_blob
e3c9314 virtio-gpu: Factor out update scanout
dbc67f1 virtio-gpu: Add helpers to create and destroy dmabuf objects
9570991 ui/pixman: Add qemu_pixman_to_drm_format()
45da29f virtio-gpu: Add virtio_gpu_resource_create_blob
2f7f18a virtio-gpu: Add initial definitions for blob resources
7e99cae virtio-gpu: Refactor virtio_gpu_create_mapping_iov
321ce3a virtio-gpu: Refactor virtio_gpu_set_scanout
442ec4a virtio-gpu: Add virtio_gpu_find_check_resource
0d66622 virtio-gpu: Add udmabuf helpers
ae69eca headers: Add udmabuf.h
4d7d9e1 ui: Get the fd associated with udmabuf driver

=== OUTPUT BEGIN ===
1/13 Checking commit 4d7d9e1eb3e4 (ui: Get the fd associated with udmabuf driver)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#45: 
new file mode 100644

total: 0 errors, 1 warnings, 54 lines checked

Patch 1/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/13 Checking commit ae69eca3ab23 (headers: Add udmabuf.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#21: 
new file mode 100644

total: 0 errors, 1 warnings, 53 lines checked

Patch 2/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/13 Checking commit 0d66622c5482 (virtio-gpu: Add udmabuf helpers)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#42: 
new file mode 100644

total: 0 errors, 1 warnings, 212 lines checked

Patch 3/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
4/13 Checking commit 442ec4a6a78d (virtio-gpu: Add virtio_gpu_find_check_resource)
5/13 Checking commit 321ce3a6fd5a (virtio-gpu: Refactor virtio_gpu_set_scanout)
6/13 Checking commit 7e99cae8610f (virtio-gpu: Refactor virtio_gpu_create_mapping_iov)
7/13 Checking commit 2f7f18ac97ad (virtio-gpu: Add initial definitions for blob resources)
8/13 Checking commit 45da29ff2830 (virtio-gpu: Add virtio_gpu_resource_create_blob)
9/13 Checking commit 957099133aa4 (ui/pixman: Add qemu_pixman_to_drm_format())
10/13 Checking commit dbc67f12bb53 (virtio-gpu: Add helpers to create and destroy dmabuf objects)
ERROR: code indent should never use tabs
#80: FILE: hw/display/virtio-gpu-udmabuf.c:216:
+^I^I^Inew_primary->buf.width,$

total: 1 errors, 0 warnings, 117 lines checked

Patch 10/13 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

11/13 Checking commit e3c9314bc71a (virtio-gpu: Factor out update scanout)
12/13 Checking commit 05f9981acd94 (virtio-gpu: Add virtio_gpu_set_scanout_blob)
13/13 Checking commit 128a9d200bdc (virtio-gpu: Update cursor data using blob)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20210519001414.786439-1-vivek.kasireddy@intel.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers
  2021-05-19  0:14 ` [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers Vivek Kasireddy
@ 2021-05-19  6:13   ` Gerd Hoffmann
  2021-05-20  6:23     ` Kasireddy, Vivek
  2021-05-24 20:37     ` Kasireddy, Vivek
  0 siblings, 2 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2021-05-19  6:13 UTC (permalink / raw)
  To: Vivek Kasireddy; +Cc: qemu-devel

> +#ifdef CONFIG_LINUX

> +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)

> +#else

> +void *virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> +{
> +    /* nothing (stub) */
> +    return NULL
> +}

Fails to build for !linux ...

You can place the stubs in a file in the stubs/ directory instead.
They'll be used via weak symbol references instead of #ifdefs then.

Advantage: the stubs are compiled unconditionally so errors like this
don't go unnoticed that easily.

take care,
  Gerd



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

* Re: [PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects
  2021-05-19  0:14 ` [PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects Vivek Kasireddy
@ 2021-05-19  6:17   ` Gerd Hoffmann
  0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2021-05-19  6:17 UTC (permalink / raw)
  To: Vivek Kasireddy; +Cc: qemu-devel

> +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_scanout *scanout = &g->parent_obj.scanout[scanout_id];
> +    VGPUDMABuf *new_primary, *old_primary;
> +
> +    new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb);
> +    if (!new_primary) {
> +        return -EINVAL;
> +    }
> +
> +    if (g->dmabuf.primary) {
> +        old_primary = g->dmabuf.primary;
> +    }
> +
> +    g->dmabuf.primary = new_primary;
> +    qemu_console_resize(scanout->con,
> +			new_primary->buf.width,
> +                        new_primary->buf.height);
> +    dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
> +
> +    if (old_primary) {
> +        virtio_gpu_free_dmabuf(g, old_primary);
> +    }
> +
> +    return 0;
> +}

../../hw/display/virtio-gpu-udmabuf.c: In function ‘virtio_gpu_update_dmabuf’:
/home/kraxel/projects/qemu/include/qemu/queue.h:456:62: error: ‘old_primary’ may be used uninitialized in this function [-Werror=maybe-uninitialized]

take care,
  Gerd



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

* RE: [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers
  2021-05-19  6:13   ` Gerd Hoffmann
@ 2021-05-20  6:23     ` Kasireddy, Vivek
  2021-05-20  9:50       ` Gerd Hoffmann
  2021-05-24 20:37     ` Kasireddy, Vivek
  1 sibling, 1 reply; 21+ messages in thread
From: Kasireddy, Vivek @ 2021-05-20  6:23 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

Hi Gerd,
 
> > +#ifdef CONFIG_LINUX
> 
> > +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> 
> > +#else
> 
> > +void *virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> > +{
> > +    /* nothing (stub) */
> > +    return NULL
> > +}
> 
> Fails to build for !linux ...
> 
> You can place the stubs in a file in the stubs/ directory instead.
> They'll be used via weak symbol references instead of #ifdefs then.
[Kasireddy, Vivek] Will do; should I send the whole series (v6) again with this and the
other error in patch #10 fixed or just the fixed versions of these specific patches?

Sorry for the tangential discussion...
On a completely different topic, I wanted to ask a question on behalf of a colleague who
is trying to enable passthrough with virtio-gpu but for a Windows guest. It appears the
guest boots only if we specify the option -vga virtio (not sure what happens with virtio=std)
as Windows launches a "Microsoft Basic Display Adapter" driver for this VGA device 
and Qemu displays the Desktop for this device (via the calls in virtio-vga.c). However,
since we only care about virtio-gpu-pci device for which we created a guest driver, we 
want to have Qemu display the content/fb from virtio-gpu instead of the vga device. 
I see that in set_scanout:

g->parent_obj.enable = 1;
and, then this in virtio-vga.c:

static void virtio_vga_base_update_display(void *opaque)                                                                                                                                                          VirtIOVGABase *vvga = opaque;                                                                                                                                                                                      VirtIOGPUBase *g = vvga->vgpu;                                                                                                                                                                                                                                                                                                                                                                                                        if (g->enable) {
    g->hw_ops->gfx_update(g);
} else {
    vvga->vga.hw_ops->gfx_update(&vvga->vga);
}

Since the parent_obj is different the above code is always going into the else part. 
Is the goal here to show the content from virtio-gpu if there is a set_scanout?

The only way we are able to get everything to work as expected is to enable our virtio-gpu
guest driver for the VGA device instead of the virtio-gpu PCI device. But we are not sure
if this would be OK or not. We don't run into these issues for Linux guests as we only 
enable virtio-gpu-pci as we have -vga none. We'd like to the do the same for Windows
guests but it looks like it needs the VGA device to be available to boot. So, our other
option (as we cannot disable the vga device) is to have Qemu accept content only from 
virtio-gpu-pci instead of virtio-vga. Would it make sense to do this? Do you think there
is a better way to do what we are trying to do?

Thanks,
Vivek



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

* Re: [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers
  2021-05-20  6:23     ` Kasireddy, Vivek
@ 2021-05-20  9:50       ` Gerd Hoffmann
  0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2021-05-20  9:50 UTC (permalink / raw)
  To: Kasireddy, Vivek; +Cc: qemu-devel

On Thu, May 20, 2021 at 06:23:58AM +0000, Kasireddy, Vivek wrote:
> Hi Gerd,
>  
> > > +#ifdef CONFIG_LINUX
> > 
> > > +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> > 
> > > +#else
> > 
> > > +void *virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> > > +{
> > > +    /* nothing (stub) */
> > > +    return NULL
> > > +}
> > 
> > Fails to build for !linux ...
> > 
> > You can place the stubs in a file in the stubs/ directory instead.
> > They'll be used via weak symbol references instead of #ifdefs then.
> [Kasireddy, Vivek] Will do; should I send the whole series (v6) again with this and the
> other error in patch #10 fixed or just the fixed versions of these specific patches?

New series please.

> I see that in set_scanout:
> 
> g->parent_obj.enable = 1;

Yep.  When the guest configured a scanout for the first time enable is
set.  device reset clears it btw.  And set_scanout_blob should take care
to set enable too.

> VirtIOGPUBase *g = vvga->vgpu;
>
> if (g->enable) {
>     g->hw_ops->gfx_update(g);
> } else {
>     vvga->vga.hw_ops->gfx_update(&vvga->vga);
> }
> 
> Since the parent_obj is different the above code is always going into the else part. 

No.  VirtIOGPU->parent_obj actually *is* VirtIOGPUBase.

> Is the goal here to show the content from virtio-gpu if there is a set_scanout?

Yes.  The idea is to switch into virtio-gpu mode when the guest driver
did load and successfully initialized the scanout.  Go back into vga
mode when the device get reset due to reboot (or other reasons).

> The only way we are able to get everything to work as expected is to enable our virtio-gpu
> guest driver for the VGA device instead of the virtio-gpu PCI device. But we are not sure
> if this would be OK or not. We don't run into these issues for Linux guests as we only 
> enable virtio-gpu-pci as we have -vga none.

I'd suggest to run qemu with "-vga none" or "-nodefaults" so qemu will
not automatically add a display device.  Then explicitly add the device
you want.

  "-device virtio-gpu-pci" is the pure virtio-gpu.
  "-device virtio-vga" is the virtio-gpu device with vga compatibility.

Both should work just fine with both linux and windows.  The only
difference is that you'll get boot messages with virtio-vga (thanks to
vga compat mode) whereas virtio-gpu-pci doesn't display anything until
the guest display driver is loaded.

OVMF can handle both virtio-gpu-pci and virtio-vga so you should see
the grub boot menu with both devices.  A GOP (used by efifb) is only
available with virtio-vga though.  Not sure how windows behaves here,
probably it wants a GOP too for the early boot screen.

The standard vga is "-device VGA", cirrus is "-device cirrus-vga".

HTH,
  Gerd



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

* RE: [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers
  2021-05-19  6:13   ` Gerd Hoffmann
  2021-05-20  6:23     ` Kasireddy, Vivek
@ 2021-05-24 20:37     ` Kasireddy, Vivek
  2021-05-25  9:24       ` Gerd Hoffmann
  1 sibling, 1 reply; 21+ messages in thread
From: Kasireddy, Vivek @ 2021-05-24 20:37 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

Hi Gerd,

> 
> > +#ifdef CONFIG_LINUX
> 
> > +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> 
> > +#else
> 
> > +void *virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
> > +{
> > +    /* nothing (stub) */
> > +    return NULL
> > +}
> 
> Fails to build for !linux ...
> 
> You can place the stubs in a file in the stubs/ directory instead.
> They'll be used via weak symbol references instead of #ifdefs then.
> 
> Advantage: the stubs are compiled unconditionally so errors like this
> don't go unnoticed that easily.
[Kasireddy, Vivek] Gave it a try but because of res->image, we'd need to consider the
Pixman dependency. I think we have the following options to address this:
1) Add pixman dependency to stubs. This may not be acceptable given that the other
dependencies are glib, socket, etc which are pretty basic.
2) Cast the objects (such as virtio_gpu_simple_resource) as void * to the functions that
we have stubs for. This also may not be acceptable as I don't see other stubs doing this.
3) Move some core objects (such as VirtIOGPUBase and its dependencies that do not
deal with pixman) into a new header and include that in virtio-gpu.h and the new stubs
file. This seems like the way to go but needs some work as virtio-gpu.h has a lot of stuff
and is included in a lot of places. If it is not a problem, I can do this in a small separate
series but keep the ifdef for this series?

Will send out a v6 for this series soon.

Thanks,
Vivek

> 
> take care,
>   Gerd



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

* Re: [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers
  2021-05-24 20:37     ` Kasireddy, Vivek
@ 2021-05-25  9:24       ` Gerd Hoffmann
  0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2021-05-25  9:24 UTC (permalink / raw)
  To: Kasireddy, Vivek; +Cc: qemu-devel

> [Kasireddy, Vivek] Gave it a try but because of res->image, we'd need to consider the
> Pixman dependency. I think we have the following options to address this:
> 1) Add pixman dependency to stubs. This may not be acceptable given that the other
> dependencies are glib, socket, etc which are pretty basic.

res->image is a pointer not an embedded struct so this could be handled
without requiring pixman.

Beside that pixman is a core dependency for system emulation, so a
pixman dependency in stubs should not cause any trouble either.

take care,
  Gerd



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

end of thread, other threads:[~2021-05-25  9:26 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-19  0:14 [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 01/13] ui: Get the fd associated with udmabuf driver Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 02/13] headers: Add udmabuf.h Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 03/13] virtio-gpu: Add udmabuf helpers Vivek Kasireddy
2021-05-19  6:13   ` Gerd Hoffmann
2021-05-20  6:23     ` Kasireddy, Vivek
2021-05-20  9:50       ` Gerd Hoffmann
2021-05-24 20:37     ` Kasireddy, Vivek
2021-05-25  9:24       ` Gerd Hoffmann
2021-05-19  0:14 ` [PATCH v5 04/13] virtio-gpu: Add virtio_gpu_find_check_resource Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 05/13] virtio-gpu: Refactor virtio_gpu_set_scanout Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 06/13] virtio-gpu: Refactor virtio_gpu_create_mapping_iov Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 07/13] virtio-gpu: Add initial definitions for blob resources Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 08/13] virtio-gpu: Add virtio_gpu_resource_create_blob Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 09/13] ui/pixman: Add qemu_pixman_to_drm_format() Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 10/13] virtio-gpu: Add helpers to create and destroy dmabuf objects Vivek Kasireddy
2021-05-19  6:17   ` Gerd Hoffmann
2021-05-19  0:14 ` [PATCH v5 11/13] virtio-gpu: Factor out update scanout Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 12/13] virtio-gpu: Add virtio_gpu_set_scanout_blob Vivek Kasireddy
2021-05-19  0:14 ` [PATCH v5 13/13] virtio-gpu: Update cursor data using blob Vivek Kasireddy
2021-05-19  0:48 ` [PATCH v5 00/13] virtio-gpu: Add support for Blob resources feature (v5) no-reply

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.