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
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
© 2016 - 2025 Red Hat, Inc.