aboutsummaryrefslogtreecommitdiff
path: root/hw/display/virtio-gpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/display/virtio-gpu.c')
-rw-r--r--hw/display/virtio-gpu.c67
1 files changed, 50 insertions, 17 deletions
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 3c96f8e26d..1cb4002e0e 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -755,6 +755,39 @@ static void virtio_gpu_handle_cursor_cb(VirtIODevice *vdev, VirtQueue *vq)
qemu_bh_schedule(g->cursor_bh);
}
+void virtio_gpu_process_cmdq(VirtIOGPU *g)
+{
+ struct virtio_gpu_ctrl_command *cmd;
+
+ while (!QTAILQ_EMPTY(&g->cmdq)) {
+ cmd = QTAILQ_FIRST(&g->cmdq);
+
+ /* process command */
+ VIRGL(g, virtio_gpu_virgl_process_cmd, virtio_gpu_simple_process_cmd,
+ g, cmd);
+ if (cmd->waiting) {
+ break;
+ }
+ QTAILQ_REMOVE(&g->cmdq, cmd, next);
+ if (virtio_gpu_stats_enabled(g->conf)) {
+ g->stats.requests++;
+ }
+
+ if (!cmd->finished) {
+ QTAILQ_INSERT_TAIL(&g->fenceq, cmd, next);
+ g->inflight++;
+ if (virtio_gpu_stats_enabled(g->conf)) {
+ if (g->stats.max_inflight < g->inflight) {
+ g->stats.max_inflight = g->inflight;
+ }
+ fprintf(stderr, "inflight: %3d (+)\r", g->inflight);
+ }
+ } else {
+ g_free(cmd);
+ }
+ }
+}
+
static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOGPU *g = VIRTIO_GPU(vdev);
@@ -776,26 +809,14 @@ static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
cmd->vq = vq;
cmd->error = 0;
cmd->finished = false;
- if (virtio_gpu_stats_enabled(g->conf)) {
- g->stats.requests++;
- }
-
- VIRGL(g, virtio_gpu_virgl_process_cmd, virtio_gpu_simple_process_cmd,
- g, cmd);
- if (!cmd->finished) {
- QTAILQ_INSERT_TAIL(&g->fenceq, cmd, next);
- g->inflight++;
- if (virtio_gpu_stats_enabled(g->conf)) {
- if (g->stats.max_inflight < g->inflight) {
- g->stats.max_inflight = g->inflight;
- }
- fprintf(stderr, "inflight: %3d (+)\r", g->inflight);
- }
- cmd = g_new(struct virtio_gpu_ctrl_command, 1);
- }
+ cmd->waiting = false;
+ QTAILQ_INSERT_TAIL(&g->cmdq, cmd, next);
+ cmd = g_new(struct virtio_gpu_ctrl_command, 1);
}
g_free(cmd);
+ virtio_gpu_process_cmdq(g);
+
#ifdef CONFIG_VIRGL
if (g->use_virgl_renderer) {
virtio_gpu_virgl_fence_poll(g);
@@ -876,11 +897,22 @@ static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
return 0;
}
+static void virtio_gpu_gl_block(void *opaque, bool block)
+{
+ VirtIOGPU *g = opaque;
+
+ g->renderer_blocked = block;
+ if (!block) {
+ virtio_gpu_process_cmdq(g);
+ }
+}
+
const GraphicHwOps virtio_gpu_ops = {
.invalidate = virtio_gpu_invalidate_display,
.gfx_update = virtio_gpu_update_display,
.text_update = virtio_gpu_text_update,
.ui_info = virtio_gpu_ui_info,
+ .gl_block = virtio_gpu_gl_block,
};
static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
@@ -921,6 +953,7 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g);
g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g);
QTAILQ_INIT(&g->reslist);
+ QTAILQ_INIT(&g->cmdq);
QTAILQ_INIT(&g->fenceq);
g->enabled_output_bitmask = 1;