From nobody Mon Apr 13 12:35:09 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1772826740; cv=none; d=zohomail.com; s=zohoarc; b=H8xsMlDt9FyMuhTqFkz9/X/mInK6WhRLAVu5p454+IETXaEMp7ylOpsVFWOrzEYnJyTxg5AWoEPPRT0xvSQMITmBPq/rkw8lTFmdZsys3HQPhOSo/P+xVncwFq96HoaArFa7050/5GzKLT+l66fYIp4LCihV8AeDeJCXEOxg+8E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772826740; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=howWJpF0OymlEFhH8Fw/3xWbTAfWZ7/hMcypwjVC4sI=; b=GY458W7+awLSZdMGuGNGZu7zxDN2bOiAQamkHVsJ9nKrx9tkMWiKWOK46IPrCd7IWHrkfCTe8FlcQBYzUoncitaedEjITjJxQSykt2i/ZkCIoqAa5uGoRxlotNuXDTlnEQuS5nQ7Hafke2t9Zf3Wa6CwN5Qdx1kwKpkB8InVQ1I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772826740646108.91872621832954; Fri, 6 Mar 2026 11:52:20 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vybDN-00061T-4U; Fri, 06 Mar 2026 14:52:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vybCQ-0004Cl-BR for qemu-devel@nongnu.org; Fri, 06 Mar 2026 14:51:03 -0500 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vybCN-0000R9-9m for qemu-devel@nongnu.org; Fri, 06 Mar 2026 14:51:01 -0500 Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-4852afd42ceso3855025e9.2 for ; Fri, 06 Mar 2026 11:50:58 -0800 (PST) Received: from draig.lan ([185.124.0.126]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4851fad2812sm227679535e9.1.2026.03.06.11.50.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Mar 2026 11:50:54 -0800 (PST) Received: from draig.lan (localhost [IPv6:::1]) by draig.lan (Postfix) with ESMTP id F3AA3689DA; Fri, 06 Mar 2026 19:50:49 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1772826658; x=1773431458; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=howWJpF0OymlEFhH8Fw/3xWbTAfWZ7/hMcypwjVC4sI=; b=Y5mevFZAPmU61ZbOBUAENqL7Ke27liPTEUHoyO8plSvCGwD6OWdCPVimBncoW/jcfK HPzDoutnjRei4/9BaCEMxQHQt5g60mtjx9EVUpYrQM8wjCA1nZLJAm9IBa3vcDsCCpN/ HNxozlasPhBhdhXr0dYLu/jxkRcvxl5hkBJaTnyTFsbBQNKUBzYPy1/LUR3Q84LkD2e8 z+9iU6PaZhmR6dNyznmn9+pior+RI6oCWeTUiZl7+IxgX4AFJzM3zd6t005EPqH9wY7K Nr2dHTRe8lHzkzGFCj3vPM0GZ1DOTCNTegrvbuorvnTtMVyooFWIHVngeVQlvWqBEsAr qdFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772826658; x=1773431458; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=howWJpF0OymlEFhH8Fw/3xWbTAfWZ7/hMcypwjVC4sI=; b=UW/DRuw4uCq13O02UdSDv6AxkdlTlfwGhYNBjG5B3JbeDOd1pFYhuucSfC1CdPPSlb fLlScMZXqWpXDne6WnX9vEi9xu09WCyqhUepoJ3BAqpgtIAKosisBjjIqpL4jdIojl7i K+pHkeE/eIC7rXhOwJ+IxX1Ye6BSbQDP96hl0VCdNbMCGd0yX5PPbe313BFVWgrWiBiq VP8QDbWr3wkGNUOwhuOESIFndqth3bRemh9YNGV4AHwud699kqVaKD1aQiE0lncEX2fq 2d3yVS+eirH92oPiidEoLmCxk8e5FoL5hgKn/1ZEi6OVebSr+ZTTiIF3edq4MC3lE2ql D68w== X-Gm-Message-State: AOJu0YxYYS2ifBd6CGIL4dMpjRTYIJOwrNvy/PX+Kdd6GwRybCIx4Piw eJ7SwF6YxMstVwIRMmaUOVWfkD0JcfPA2W01pT95rDOnQbqjZBkgzQqd7ZNcXLtztyA= X-Gm-Gg: ATEYQzzaOFM+VSpYoMkRne7JS6O1p5+z33JKysVc4BVeOGBJIX4r25qfbZVF/fvpdqi gsTdky56rwuMrEcMpnAg6Tesv/z100TL54YV02tNm2aEXfq98CT5/hSfAD4D5ZVUvqxMMuwX6Ba FCMPh44+vlzW/ujpM6qHNAQIBGIX8L2pMEYceCtQQafQldcTxaA7wnqZz3Fb8QCSgj1EFlUYiR8 G+AS0IRRn6Asyh1/ZGClTF6Y/GG+9dnj22jBfVrl0OCZhuJWp+b3vx28AuG+JN87IMcI9Aopub/ QGo58YYvho0nM0u++jtOsvuorki0Ejhfbrl3b77FvbwdPQZ5IjDATCre7d8Sf5DcMaYuW1kNtBe bA9RONn27hOLY9uodGCqxLyWXnONBIF4+o4KSbcyzWFUY+1tRnJUgvCCwyRWE1hOEB6au5CFA/p NXWTx3VA08nre9KmLuGCafkengBf4Yvi4tFQ== X-Received: by 2002:a05:600c:45d1:b0:483:a361:41a5 with SMTP id 5b1f17b1804b1-4852697866fmr56181425e9.30.1772826657754; Fri, 06 Mar 2026 11:50:57 -0800 (PST) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Cc: Dmitry Osipenko , Akihiko Odaki , "Michael S. Tsirkin" , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Pierre-Eric Pelloux-Prayer , Yiwei Zhang , Akihiko Odaki , Paolo Bonzini , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PULL 11/20] virtio-gpu: Support asynchronous fencing Date: Fri, 6 Mar 2026 19:50:38 +0000 Message-ID: <20260306195048.2869788-12-alex.bennee@linaro.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260306195048.2869788-1-alex.bennee@linaro.org> References: <20260306195048.2869788-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::335; envelope-from=alex.bennee@linaro.org; helo=mail-wm1-x335.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linaro.org) X-ZM-MESSAGEID: 1772826742611154100 From: Dmitry Osipenko Support asynchronous fencing feature of virglrenderer. It allows Qemu to handle fence as soon as it's signalled instead of periodically polling the fence status. This feature is required for enabling DRM context support in Qemu because legacy fencing mode isn't supported for DRM contexts in virglrenderer. Reviewed-by: Akihiko Odaki Acked-by: Michael S. Tsirkin Tested-by: Alex Benn=C3=A9e Reviewed-by: Alex Benn=C3=A9e Acked-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Yiwei Zhang Tested-by: Yiwei Zhang Signed-off-by: Dmitry Osipenko Message-ID: <20260303151422.977399-10-dmitry.osipenko@collabora.com> Message-ID: <20260304165043.1437519-12-alex.bennee@linaro.org> Signed-off-by: Alex Benn=C3=A9e diff --git a/meson.build b/meson.build index 6b1838b159e..0029c970b08 100644 --- a/meson.build +++ b/meson.build @@ -2524,6 +2524,8 @@ config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) config_host_data.set('CONFIG_VNC_SASL', sasl.found()) if virgl.found() config_host_data.set('VIRGL_VERSION_MAJOR', virgl.version().split('.')[0= ]) + config_host_data.set('VIRGL_VERSION_MINOR', virgl.version().split('.')[1= ]) + config_host_data.set('VIRGL_VERSION_MICRO', virgl.version().split('.')[2= ]) endif config_host_data.set('CONFIG_VIRTFS', have_virtfs) config_host_data.set('CONFIG_VTE', vte.found()) diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 65312f869dd..2610a32e408 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -233,6 +233,13 @@ struct VirtIOGPUClass { Error **errp); }; =20 +struct virtio_gpu_virgl_context_fence { + uint32_t ctx_id; + uint32_t ring_idx; + uint64_t fence_id; + QSLIST_ENTRY(virtio_gpu_virgl_context_fence) next; +}; + /* VirtIOGPUGL renderer states */ typedef enum { RS_START, /* starting state */ @@ -250,6 +257,9 @@ struct VirtIOGPUGL { QEMUTimer *print_stats; =20 QEMUBH *cmdq_resume_bh; + + QEMUBH *async_fence_bh; + QSLIST_HEAD(, virtio_gpu_virgl_context_fence) async_fenceq; }; =20 struct VhostUserGPU { @@ -380,5 +390,6 @@ void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g); void virtio_gpu_virgl_reset(VirtIOGPU *g); int virtio_gpu_virgl_init(VirtIOGPU *g); GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g); +void virtio_gpu_virgl_reset_async_fences(VirtIOGPU *g); =20 #endif diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c index b98ef2ef987..3e0680880e1 100644 --- a/hw/display/virtio-gpu-gl.c +++ b/hw/display/virtio-gpu-gl.c @@ -169,6 +169,11 @@ static void virtio_gpu_gl_device_unrealize(DeviceState= *qdev) if (gl->renderer_state >=3D RS_INITED) { #if VIRGL_VERSION_MAJOR >=3D 1 qemu_bh_delete(gl->cmdq_resume_bh); + + if (gl->async_fence_bh) { + virtio_gpu_virgl_reset_async_fences(g); + qemu_bh_delete(gl->async_fence_bh); + } #endif if (virtio_gpu_stats_enabled(g->parent_obj.conf)) { timer_free(gl->print_stats); diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c index f00c666f61f..ae1880c358b 100644 --- a/hw/display/virtio-gpu-virgl.c +++ b/hw/display/virtio-gpu-virgl.c @@ -24,6 +24,23 @@ =20 #include =20 +/* + * VIRGL_CHECK_VERSION available since libvirglrenderer 1.0.1 and was fixed + * in 1.1.0. Undefine bugged version of the macro and provide our own. + */ +#if defined(VIRGL_CHECK_VERSION) && \ + VIRGL_VERSION_MAJOR =3D=3D 1 && VIRGL_VERSION_MINOR < 1 +#undef VIRGL_CHECK_VERSION +#endif + +#ifndef VIRGL_CHECK_VERSION +#define VIRGL_CHECK_VERSION(major, minor, micro) \ + (VIRGL_VERSION_MAJOR > (major) || \ + VIRGL_VERSION_MAJOR =3D=3D (major) && VIRGL_VERSION_MINOR > (minor) |= | \ + VIRGL_VERSION_MAJOR =3D=3D (major) && VIRGL_VERSION_MINOR =3D=3D (min= or) && \ + VIRGL_VERSION_MICRO >=3D (micro)) +#endif + struct virtio_gpu_virgl_resource { struct virtio_gpu_simple_resource base; MemoryRegion *mr; @@ -1079,6 +1096,103 @@ static void virgl_write_context_fence(void *opaque,= uint32_t ctx_id, } #endif =20 +void virtio_gpu_virgl_reset_async_fences(VirtIOGPU *g) +{ + struct virtio_gpu_virgl_context_fence *f; + VirtIOGPUGL *gl =3D VIRTIO_GPU_GL(g); + + while (!QSLIST_EMPTY(&gl->async_fenceq)) { + f =3D QSLIST_FIRST(&gl->async_fenceq); + + QSLIST_REMOVE_HEAD(&gl->async_fenceq, next); + + g_free(f); + } +} + +#if VIRGL_CHECK_VERSION(1, 1, 2) +static void virtio_gpu_virgl_async_fence_bh(void *opaque) +{ + QSLIST_HEAD(, virtio_gpu_virgl_context_fence) async_fenceq; + struct virtio_gpu_ctrl_command *cmd, *tmp; + struct virtio_gpu_virgl_context_fence *f; + VirtIOGPU *g =3D opaque; + VirtIOGPUGL *gl =3D VIRTIO_GPU_GL(g); + + if (gl->renderer_state !=3D RS_INITED) { + return; + } + + QSLIST_MOVE_ATOMIC(&async_fenceq, &gl->async_fenceq); + + while (!QSLIST_EMPTY(&async_fenceq)) { + f =3D QSLIST_FIRST(&async_fenceq); + + QSLIST_REMOVE_HEAD(&async_fenceq, next); + + QTAILQ_FOREACH_SAFE(cmd, &g->fenceq, next, tmp) { + /* + * the guest can end up emitting fences out of order + * so we should check all fenced cmds not just the first one. + */ + if (cmd->cmd_hdr.fence_id > f->fence_id) { + continue; + } + if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_INFO_RING_IDX) { + if (cmd->cmd_hdr.ring_idx !=3D f->ring_idx) { + continue; + } + if (cmd->cmd_hdr.ctx_id !=3D f->ctx_id) { + continue; + } + } + virtio_gpu_ctrl_response_nodata(g, cmd, VIRTIO_GPU_RESP_OK_NOD= ATA); + QTAILQ_REMOVE(&g->fenceq, cmd, next); + g_free(cmd); + } + + trace_virtio_gpu_fence_resp(f->fence_id); + g_free(f); + g->inflight--; + if (virtio_gpu_stats_enabled(g->parent_obj.conf)) { + trace_virtio_gpu_dec_inflight_fences(g->inflight); + } + } +} + +static void +virtio_gpu_virgl_push_async_fence(VirtIOGPU *g, uint32_t ctx_id, + uint32_t ring_idx, uint64_t fence_id) +{ + struct virtio_gpu_virgl_context_fence *f; + VirtIOGPUGL *gl =3D VIRTIO_GPU_GL(g); + + f =3D g_new(struct virtio_gpu_virgl_context_fence, 1); + f->ctx_id =3D ctx_id; + f->ring_idx =3D ring_idx; + f->fence_id =3D fence_id; + + QSLIST_INSERT_HEAD_ATOMIC(&gl->async_fenceq, f, next); + + qemu_bh_schedule(gl->async_fence_bh); +} + +static void virgl_write_async_fence(void *opaque, uint32_t fence) +{ + VirtIOGPU *g =3D opaque; + + virtio_gpu_virgl_push_async_fence(g, 0, UINT32_MAX, fence); +} + +static void virgl_write_async_context_fence(void *opaque, uint32_t ctx_id, + uint32_t ring_idx, uint64_t fe= nce) +{ + VirtIOGPU *g =3D opaque; + + virtio_gpu_virgl_push_async_fence(g, ctx_id, ring_idx, fence); +} +#endif + static virgl_renderer_gl_context virgl_create_context(void *opaque, int scanout_idx, struct virgl_renderer_gl_ctx_param *params) @@ -1178,6 +1292,8 @@ void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g) void virtio_gpu_virgl_reset(VirtIOGPU *g) { virgl_renderer_reset(); + + virtio_gpu_virgl_reset_async_fences(g); } =20 int virtio_gpu_virgl_init(VirtIOGPU *g) @@ -1190,6 +1306,12 @@ int virtio_gpu_virgl_init(VirtIOGPU *g) if (qemu_egl_display) { virtio_gpu_3d_cbs.version =3D 4; virtio_gpu_3d_cbs.get_egl_display =3D virgl_get_egl_display; +#if VIRGL_CHECK_VERSION(1, 1, 2) + virtio_gpu_3d_cbs.write_fence =3D virgl_write_async_fence; + virtio_gpu_3d_cbs.write_context_fence =3D virgl_write_async_contex= t_fence; + flags |=3D VIRGL_RENDERER_ASYNC_FENCE_CB; + flags |=3D VIRGL_RENDERER_THREAD_SYNC; +#endif } #endif #ifdef VIRGL_RENDERER_D3D11_SHARE_TEXTURE @@ -1223,6 +1345,11 @@ int virtio_gpu_virgl_init(VirtIOGPU *g) gl->cmdq_resume_bh =3D virtio_bh_io_new_guarded(DEVICE(g), virtio_gpu_virgl_resume_= cmdq_bh, g); +#if VIRGL_CHECK_VERSION(1, 1, 2) + gl->async_fence_bh =3D virtio_bh_io_new_guarded(DEVICE(g), + virtio_gpu_virgl_async_f= ence_bh, + g); +#endif #endif =20 return 0; --=20 2.47.3