From: Lei Huang <Lei.Huang@amd.com>
To: <mst@redhat.com>
Cc: <leihuang@amd.com>, <pierre-eric.pelloux-prayer@amd.com>,
<ken.xue@amd.com>, <qemu-devel@nongnu.org>,
Lei Huang <Lei.Huang@amd.com>
Subject: [PATCH v2 1/1] virtio-gpu: customize EDID for vms
Date: Thu, 1 Aug 2024 10:53:33 +0800 [thread overview]
Message-ID: <20240801025334.1610-2-Lei.Huang@amd.com> (raw)
In-Reply-To: <20240801025334.1610-1-Lei.Huang@amd.com>
customize refresh rate and resolution for the guest VM
instead of being limited by the actual resolution of the host.
add edid info and modify conf like:
"-device", "virtio-vga-gl,edid=on,max_outputs=2,
refresh_rate0=120000,maxx0=7680,maxy0=1080,refresh_rate1=75000,
maxx1=3840,maxy1=960"
Change-Id: I5d5742d280186ffd5dee9eba7697f06a2b09b123
Signed-off-by: Lei Huang <Lei.Huang@amd.com>
---
hw/display/virtio-gpu-base.c | 41 ++++++++++++++++++++++++++++------
hw/display/virtio-gpu.c | 1 +
include/hw/virtio/virtio-gpu.h | 26 +++++++++++++++++++++
3 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index 4fc7ef8896c..80d22005447 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -46,8 +46,18 @@ virtio_gpu_base_fill_display_info(VirtIOGPUBase *g,
for (i = 0; i < g->conf.max_outputs; i++) {
if (g->enabled_output_bitmask & (1 << i)) {
dpy_info->pmodes[i].enabled = 1;
- dpy_info->pmodes[i].r.width = cpu_to_le32(g->req_state[i].width);
- dpy_info->pmodes[i].r.height = cpu_to_le32(g->req_state[i].height);
+ if (g->edid_info[i].maxx && g->edid_info[i].maxy &&
+ virtio_gpu_edid_enabled(g->conf)) {
+ dpy_info->pmodes[i].r.width =
+ cpu_to_le32(g->edid_info[i].maxx);
+ dpy_info->pmodes[i].r.height =
+ cpu_to_le32(g->edid_info[i].maxy);
+ } else {
+ dpy_info->pmodes[i].r.width =
+ cpu_to_le32(g->req_state[i].width);
+ dpy_info->pmodes[i].r.height =
+ cpu_to_le32(g->req_state[i].height);
+ }
}
}
}
@@ -62,6 +72,8 @@ virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int scanout,
.prefx = g->req_state[scanout].width,
.prefy = g->req_state[scanout].height,
.refresh_rate = g->req_state[scanout].refresh_rate,
+ .maxx = g->req_state[scanout].width,
+ .maxy = g->req_state[scanout].height,
};
edid->size = cpu_to_le32(sizeof(edid->edid));
@@ -96,9 +108,16 @@ static void virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
g->req_state[idx].x = info->xoff;
g->req_state[idx].y = info->yoff;
- g->req_state[idx].refresh_rate = info->refresh_rate;
- g->req_state[idx].width = info->width;
- g->req_state[idx].height = info->height;
+ if (!g->edid_info[idx].refresh_rate) {
+ g->req_state[idx].refresh_rate = info->refresh_rate;
+ }
+ if (!g->edid_info[idx].maxx) {
+ g->req_state[idx].width = info->width;
+ }
+ if (!g->edid_info[idx].maxy) {
+ g->req_state[idx].height = info->height;
+ }
+
g->req_state[idx].width_mm = info->width_mm;
g->req_state[idx].height_mm = info->height_mm;
@@ -204,11 +223,19 @@ virtio_gpu_base_device_realize(DeviceState *qdev,
g->enabled_output_bitmask = 1;
- g->req_state[0].width = g->conf.xres;
- g->req_state[0].height = g->conf.yres;
g->hw_ops = &virtio_gpu_ops;
for (i = 0; i < g->conf.max_outputs; i++) {
+ if (g->edid_info[i].maxx && g->edid_info[i].maxy &&
+ virtio_gpu_edid_enabled(g->conf) &&
+ g->edid_info[i].refresh_rate) {
+ g->req_state[i].refresh_rate = g->edid_info[i].refresh_rate;
+ g->req_state[i].width = g->edid_info[i].maxx;
+ g->req_state[i].height = g->edid_info[i].maxy;
+ } else {
+ g->req_state[i].width = g->conf.xres;
+ g->req_state[i].height = g->conf.yres;
+ }
g->scanout[i].con =
graphic_console_init(DEVICE(g), i, &virtio_gpu_ops, g);
}
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 3281842bfe1..dd759a80522 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1666,6 +1666,7 @@ static const VMStateDescription vmstate_virtio_gpu = {
static Property virtio_gpu_properties[] = {
VIRTIO_GPU_BASE_PROPERTIES(VirtIOGPU, parent_obj.conf),
+ VIRTIO_GPU_EDID_PROPERTIES_MULTI_DISPLAY(VirtIOGPU, parent_obj.edid_info),
DEFINE_PROP_SIZE("max_hostmem", VirtIOGPU, conf_max_hostmem,
256 * MiB),
DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 7a59379f5a7..61c69735dba 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -18,6 +18,7 @@
#include "ui/qemu-pixman.h"
#include "ui/console.h"
#include "hw/virtio/virtio.h"
+#include "hw/display/edid.h"
#include "qemu/log.h"
#include "sysemu/vhost-user-backend.h"
@@ -150,6 +151,7 @@ struct VirtIOGPUBase {
MemoryRegion hostmem;
struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
+ struct qemu_edid_info edid_info[VIRTIO_GPU_MAX_SCANOUTS];
int enabled_output_bitmask;
struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
@@ -168,6 +170,30 @@ struct VirtIOGPUBaseClass {
DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1280), \
DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800)
+#define VIRTIO_GPU_EDID_PROPERTIES_MULTI_DISPLAY(_state, _edid_info) \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 0), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 1), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 2), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 3), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 4), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 5), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 6), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 7), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 8), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 9), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 10), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 11), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 12), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 13), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 14), \
+ VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, 15) \
+
+#define VIRTIO_GPU_EDID_PROPERTIES(_state, _edid_info, id) \
+ DEFINE_PROP_UINT32("maxx" #id, _state, _edid_info[id].maxx, 0), \
+ DEFINE_PROP_UINT32("maxy" #id, _state, _edid_info[id].maxy, 0), \
+ DEFINE_PROP_UINT32("refresh_rate" #id, _state, \
+ _edid_info[id].refresh_rate, 0)
+
typedef struct VGPUDMABuf {
QemuDmaBuf *buf;
uint32_t scanout_id;
--
2.45.2
prev parent reply other threads:[~2024-08-01 7:36 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-01 2:53 [PATCH v2 0/1] Brief description of the patch series Lei Huang
2024-08-01 2:53 ` Lei Huang [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240801025334.1610-2-Lei.Huang@amd.com \
--to=lei.huang@amd.com \
--cc=ken.xue@amd.com \
--cc=leihuang@amd.com \
--cc=mst@redhat.com \
--cc=pierre-eric.pelloux-prayer@amd.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).