[RFC PATCH 2/2] virtio-gpu: Add an option to connect all outputs on startup

Damian Hobson-Garcia posted 2 patches 2 years, 2 months ago
[RFC PATCH 2/2] virtio-gpu: Add an option to connect all outputs on startup
Posted by Damian Hobson-Garcia 2 years, 2 months ago
When multiple outputs are enabled using the "max_outputs" attribute,
only the first connector appears as "Connected" in the guest DRM
device.  Additional connectors must be enabled from the host side
UI frontend before they are usable by the guest.  However, multiple
outputs can still be of use on a headless configuration, if for example,
the display will only be used for taking periodic screenshots in the
guest or integration into a CI pipeline, etc.

Add an option to start all of the outputs in the "Connected" state,
so that they are immediately available to the guest.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1107
Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
---
 hw/display/virtio-gpu-base.c   | 12 +++++++++---
 include/hw/virtio/virtio-gpu.h |  7 ++++++-
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index a29f191aa8..885184e302 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -158,6 +158,7 @@ virtio_gpu_base_device_realize(DeviceState *qdev,
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
     VirtIOGPUBase *g = VIRTIO_GPU_BASE(qdev);
+    int connected = 1;
     int i;
 
     if (g->conf.max_outputs > VIRTIO_GPU_MAX_SCANOUTS) {
@@ -186,10 +187,15 @@ virtio_gpu_base_device_realize(DeviceState *qdev,
         virtio_add_queue(vdev, 16, cursor_cb);
     }
 
-    g->enabled_output_bitmask = 1;
+    if (virtio_gpu_connect_all_outputs(g->conf))
+        connected = g->conf.max_outputs;
 
-    g->req_state[0].width = g->conf.xres;
-    g->req_state[0].height = g->conf.yres;
+    g->enabled_output_bitmask = (1 << connected) - 1;
+
+    for (i = 0; i < connected; i++) {
+        g->req_state[i].width = g->conf.xres;
+        g->req_state[i].height = g->conf.yres;
+    }
 
     g->hw_ops = &virtio_gpu_ops;
     for (i = 0; i < g->conf.max_outputs; i++) {
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 2e28507efe..54b3eba632 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -90,6 +90,7 @@ enum virtio_gpu_base_conf_flags {
     VIRTIO_GPU_FLAG_EDID_ENABLED,
     VIRTIO_GPU_FLAG_DMABUF_ENABLED,
     VIRTIO_GPU_FLAG_BLOB_ENABLED,
+    VIRTIO_GPU_FLAG_CONNECT_ALL_OUTPUTS,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -102,6 +103,8 @@ enum virtio_gpu_base_conf_flags {
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED))
 #define virtio_gpu_blob_enabled(_cfg) \
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
+#define virtio_gpu_connect_all_outputs(_cfg) \
+    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONNECT_ALL_OUTPUTS))
 
 struct virtio_gpu_base_conf {
     uint32_t max_outputs;
@@ -148,7 +151,9 @@ struct VirtIOGPUBaseClass {
     DEFINE_PROP_BIT("edid", _state, _conf.flags, \
                     VIRTIO_GPU_FLAG_EDID_ENABLED, true), \
     DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1280), \
-    DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800)
+    DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800), \
+    DEFINE_PROP_BIT("connect_outputs", _state, _conf.flags, \
+                    VIRTIO_GPU_FLAG_CONNECT_ALL_OUTPUTS, false)
 
 typedef struct VGPUDMABuf {
     QemuDmaBuf buf;
-- 
2.25.1
Re: [RFC PATCH 2/2] virtio-gpu: Add an option to connect all outputs on startup
Posted by Damian Hobson-Garcia 2 years, 1 month ago
On 2023/03/08 11:25, Damian Hobson-Garcia wrote:
> When multiple outputs are enabled using the "max_outputs" attribute,
> only the first connector appears as "Connected" in the guest DRM
> device.  Additional connectors must be enabled from the host side
> UI frontend before they are usable by the guest.  However, multiple
> outputs can still be of use on a headless configuration, if for example,
> the display will only be used for taking periodic screenshots in the
> guest or integration into a CI pipeline, etc.
> 
> Add an option to start all of the outputs in the "Connected" state,
> so that they are immediately available to the guest.

I was also thinking that since the main application for this is headless 
configurations, it could be possible to implement this in
ui/egl-headless.c.

Calling dpy_set_ui_info() for each console during initialization is 
enough to enable the outputs, but then there is the question of what 
resolution to pass in the ui_info. Hardcoded? Add a new option to the 
`egl-headless` display property?

Are there any thoughts on this approach vs. addressing this at the 
display driver (virtio-gpu) level?

Thank you,
Damian