On 2026/02/18 6:49, Dmitry Osipenko wrote:
VirtIO-GPU commands may be processed outside of main-loop, from a CPU
thread. This results in GL context switch failure because context is held
by main-loop thread when GL is invoked from CPU thread. Always release GL
context after performing GL operations such that other threads could take
over the context.
0 SDL_GL_MakeCurrent() (libSDL3)
1 SDL_GL_MakeCurrent_REAL() (libSDL2)
2 sdl2_gl_make_context_current() (ui/sdl2-gl.c:201)
3 make_current() (virglrenderer.c:639)
4 vrend_finish_context_switch() (vrend_renderer.c:11630)
5 vrend_hw_switch_context() (vrend_renderer.c:11613)
6 vrend_renderer_force_ctx_0() (vrend_renderer.c:12986)
7 virgl_renderer_force_ctx_0() (virglrenderer.c:460)
8 virtio_gpu_virgl_process_cmd() (virtio-gpu-virgl.c:1013)
9 virtio_gpu_process_cmdq() (virtio-gpu.c:1050)
10 virtio_gpu_gl_handle_ctrl() (virtio-gpu-gl.c:86)
11 aio_bh_poll() (util/async.c)
12 aio_poll() (util/aio-posix.c)
13 blk_pwrite() (block/block-gen.c:1985)
14 pflash_update() (pflash_cfi01.c:396)
15 pflash_write() (pflash_cfi01.c:541)
16 memory_region_dispatch_write() (system/memory.c:1554)
17 flatview_write() (system/physmem.c:3333)
18 address_space_write() (system/physmem.c:3453)
19 kvm_cpu_exec() (accel/kvm/kall-all.c:3248)
20 kvm_vcpu_thread_fn() (accel/kvm/kaccel-ops.c:53)
Signed-off-by: Dmitry Osipenko <[email protected]>
---
hw/display/virtio-gpu-virgl.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 0f754829fb71..0021df45d4b2 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -896,14 +896,20 @@ static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
}
#endif
-void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
- struct virtio_gpu_ctrl_command *cmd)
+static void virtio_gpu_virgl_unset_ctx_0(VirtIOGPU *g)
+{
+ /* Virglrender always uses first scanout for GL. */
+ dpy_gl_ctx_make_current(g->parent_obj.scanout[0].con, NULL);
"unset_ctx_0" is a misnomer. It uses the scanout with index 0, but "0"
in virgl_renderer_force_ctx_0() refers to a context, not scanout.
virglrenderer creates multiple contexts; it creates contexts as the
guest requests, and also creates one special context that performs
operations not bound to the contexts the guest requested to create. The
special context is called "ctx_0".
When unsetting a context, it does not matter what context is currently
set, so it should just say "ctx", not "ctx_0".
By the way, writing this email, I found the use of phrase "setting a
context" is unusual. "Binding" is more conventional, and that's what the
EGL specification uses for eglMakeCurrent(). So, this function should be
named "unbind_ctx" or something like that.
Regards,
Akihiko Odaki