On 2026/08/25 19:20, Marc-André Lureau wrote:
The rutabaga backend was misusing the scanout_bitmask field as a
plain scanout ID instead of a bitmask.

Fix the scanout lookup to use scanout->resource_id directly. Also
fix the missing resource_id clear when disabling a scanout, and
flush all matching scanouts instead of just the first one.


Fixes: 1dcc6adbc168 ("gfxstream + rutabaga: add initial support for gfxstream")

Signed-off-by: Marc-André Lureau <[email protected]>
---
  hw/display/virtio-gpu-rutabaga.c | 20 +++++++++++++++++---
  1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
index a054f8117f14..fcd9c94d580c 100644
--- a/hw/display/virtio-gpu-rutabaga.c
+++ b/hw/display/virtio-gpu-rutabaga.c
@@ -154,8 +154,15 @@ virtio_gpu_rutabaga_resource_unref(VirtIOGPU *g,
                                     Error **errp)
  {
      int32_t result;
+    int i;
      VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g);
+ for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
+        if (g->parent_obj.scanout[i].resource_id == res->resource_id) {
+            virtio_gpu_disable_scanout(g, i);
+        }
+    }
+
      result = rutabaga_resource_unref(vr->rutabaga, res->resource_id);
      if (result) {
          error_setg_errno(errp,
@@ -259,7 +266,7 @@ rutabaga_cmd_resource_flush(VirtIOGPU *g, struct 
virtio_gpu_ctrl_command *cmd)
for (i = 0; i < vb->conf.max_outputs; i++) {
          scanout = &vb->scanout[i];
-        if (i == res->scanout_bitmask) {
+        if (scanout->resource_id == res->resource_id) {
              found = true;
              break;
          }
@@ -283,7 +290,13 @@ rutabaga_cmd_resource_flush(VirtIOGPU *g, struct 
virtio_gpu_ctrl_command *cmd)
                                               rf.resource_id, &transfer,
                                               &transfer_iovec);
      CHECK(!result, cmd);
-    qemu_console_update_full(scanout->con);
+
+    for (i = 0; i < vb->conf.max_outputs; i++) {
+        scanout = &vb->scanout[i];
+        if (scanout->resource_id == res->resource_id) {
+            qemu_console_update_full(scanout->con);
+        }
+    }
  }
static void
@@ -307,6 +320,7 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct 
virtio_gpu_ctrl_command *cmd)
      scanout = &vb->scanout[ss.scanout_id];
if (ss.resource_id == 0) {
+        scanout->resource_id = 0;
          qemu_console_set_surface(scanout->con, NULL);
          qemu_console_gl_scanout_disable(scanout->con);
          return;
@@ -340,7 +354,7 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct 
virtio_gpu_ctrl_command *cmd)
      scanout->ds = qemu_create_displaysurface_pixman(res->image);
      qemu_console_set_surface(scanout->con, NULL);
      qemu_console_set_surface(scanout->con, scanout->ds);
-    res->scanout_bitmask = ss.scanout_id;
+    scanout->resource_id = ss.resource_id;
  }
static void



Reply via email to