feat: support installed guests and distribution display defaults

This commit is contained in:
Codex
2026-10-13 04:27:06 +03:00
parent 533ae511b8
commit 48ee598e9f
8 changed files with 299 additions and 24 deletions
+71
View File
@@ -0,0 +1,71 @@
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -128,6 +128,7 @@
uint32_t flags;
uint32_t xres;
uint32_t yres;
+ uint32_t refresh_rate;
uint64_t hostmem;
VirtIOGPUOutputList *outputs;
};
@@ -173,7 +174,8 @@
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_UINT32("refresh_rate", _state, _conf.refresh_rate, 0)
typedef struct VGPUDMABuf {
QemuDmaBuf *buf;
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -64,7 +64,9 @@
.height_mm = g->req_state[scanout].height_mm,
.prefx = g->req_state[scanout].width,
.prefy = g->req_state[scanout].height,
- .refresh_rate = g->req_state[scanout].refresh_rate,
+ /* An explicit monitor refresh rate, in mHz, survives UI resizes. */
+ .refresh_rate = g->conf.refresh_rate ? g->conf.refresh_rate :
+ g->req_state[scanout].refresh_rate,
};
for (output_idx = 0, node = g->conf.outputs;
--- a/hw/display/edid-generate.c
+++ b/hw/display/edid-generate.c
@@ -220,17 +220,17 @@
desc[5 + len] = '\n';
}
-static void edid_desc_ranges(uint8_t *desc)
+static void edid_desc_ranges(uint8_t *desc, uint32_t refresh_rate,
+ uint32_t horizontal_rate)
{
edid_desc_type(desc, 0xfd);
- /* vertical (50 -> 125 Hz) */
- desc[5] = 50;
- desc[6] = 125;
-
- /* horizontal (30 -> 160 kHz) */
- desc[7] = 30;
- desc[8] = 160;
+ /* Preserve the legacy ranges and include the preferred mode. */
+ desc[5] = 50;
+ desc[6] = MIN(255, MAX(125, DIV_ROUND_UP(refresh_rate, 1000)));
+
+ desc[7] = 30;
+ desc[8] = MIN(255, MAX(160, DIV_ROUND_UP(horizontal_rate, 1000)));
/* max dot clock (2550 MHz) */
desc[9] = 2550 / 10;
@@ -513,7 +513,8 @@
* so dta descriptor offsets don't move any more.
*/
- edid_desc_ranges(desc);
+ edid_desc_ranges(desc, refresh_rate,
+ timings.clock * 10000 / (info->prefx + timings.xblank));
desc = edid_desc_next(edid, dta, desc);
if (desc && info->name) {