@samitouri / QOSamiQemu / commits / 893598209f

virtio-gpu: Support DRM native context

Add support for DRM native contexts to VirtIO-GPU. DRM context is enabled using a new virtio-gpu-gl device option "drm_native_context=on". Unlike Virgl and Venus contexts that operate on application API level, DRM native contexts work on a kernel UAPI level. This lower level results in a lightweight context implementations that yield better performance. Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Tested-by: Alex Bennée <alex.bennee@linaro.org> Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Reviewed-by: Yiwei Zhang <zzyiwei@gmail.com> Tested-by: Yiwei Zhang <zzyiwei@gmail.com> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Message-ID: <20260303151422.977399-11-dmitry.osipenko@collabora.com> Message-ID: <20260304165043.1437519-13-alex.bennee@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

Dmitry Osipenko committed Mar 4, 2026 at 16:50 UTC 893598209fde32ca5f013a012b120af3a458bcae
5 files changed +59
docs/system/devices/virtio/virtio-gpu.rst
+11
@@ -84,6 +84,17 @@ of virtio-gpu host memory window. This is typically between 256M and 8G.
84
85 .. _venus: https://gitlab.freedesktop.org/virgl/venus-protocol/
86
87 +DRM native context is supported since release of `virglrenderer`_ v1.0.0
88 +using `drm`_ protocol. ``DRM`` virtio-gpu capability set ("capset") requires
89 +host blob support (``hostmem`` and ``blob`` fields) and should be enabled
90 +using ``drm_native_context`` field. The ``hostmem`` field specifies the size
91 +of virtio-gpu host memory window. This is typically between 256M and 8G.
92 +
93 +.. parsed-literal::
94 + -device virtio-gpu-gl,hostmem=8G,blob=on,drm_native_context=on
95 +
96 +.. _drm: https://gitlab.freedesktop.org/virgl/virglrenderer/-/tree/main/src/drm
97 +
98 virtio-gpu rutabaga
99 -------------------
100
hw/display/virtio-gpu-gl.c
+2
@@ -159,6 +159,8 @@ static const Property virtio_gpu_gl_properties[] = {
159 VIRTIO_GPU_FLAG_STATS_ENABLED, false),
160 DEFINE_PROP_BIT("venus", VirtIOGPU, parent_obj.conf.flags,
161 VIRTIO_GPU_FLAG_VENUS_ENABLED, false),
162 + DEFINE_PROP_BIT("drm_native_context", VirtIOGPU, parent_obj.conf.flags,
163 + VIRTIO_GPU_FLAG_DRM_ENABLED, false),
164 };
165
166 static void virtio_gpu_gl_device_unrealize(DeviceState *qdev)
hw/display/virtio-gpu-virgl.c
+28
@@ -1323,6 +1323,25 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
1323 if (virtio_gpu_venus_enabled(g->parent_obj.conf)) {
1324 flags |= VIRGL_RENDERER_VENUS | VIRGL_RENDERER_RENDER_SERVER;
1325 }
1326 + if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
1327 + flags |= VIRGL_RENDERER_DRM;
1328 +
1329 + if (!(flags & VIRGL_RENDERER_ASYNC_FENCE_CB)) {
1330 + /*
1331 + * Virglrenderer skips enabling DRM context support without
1332 + * enabled async-fence feature. VirtIO-GPU will initialize
1333 + * successfully, but DRM context won't be available in guest.
1334 + *
1335 + * For vrend async-fencing can be enabled only if EGL display
1336 + * is used. Vrend can't be disabled in QEMU, hence DRM implicitly
1337 + * requires EGL too.
1338 + *
1339 + * Async-fence was bugged in virglrenderer versions <= 1.1.1.
1340 + */
1341 + error_report("drm requires egl display and virglrenderer >= 1.2.0");
1342 + return -EINVAL;
1343 + }
1344 + }
1345 #endif
1346
1347 ret = virgl_renderer_init(g, flags, &virtio_gpu_3d_cbs);
@@ -1386,5 +1405,14 @@ GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g)
1405 }
1406 }
1407
1408 + if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
1409 + virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_DRM,
1410 + &capset_max_ver,
1411 + &capset_max_size);
1412 + if (capset_max_size) {
1413 + virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_DRM);
1414 + }
1415 + }
1416 +
1417 return capset_ids;
1418 }
hw/display/virtio-gpu.c
+15
@@ -1517,6 +1517,21 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
1517 #endif
1518 }
1519
1520 + if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
1521 +#ifdef VIRGL_VERSION_MAJOR
1522 + #if VIRGL_VERSION_MAJOR >= 1
1523 + if (!virtio_gpu_blob_enabled(g->parent_obj.conf) ||
1524 + !virtio_gpu_hostmem_enabled(g->parent_obj.conf)) {
1525 + error_setg(errp, "drm requires enabled blob and hostmem options");
1526 + return;
1527 + }
1528 + #else
1529 + error_setg(errp, "old virglrenderer, drm unsupported");
1530 + return;
1531 + #endif
1532 +#endif
1533 + }
1534 +
1535 if (!virtio_gpu_base_device_realize(qdev,
1536 virtio_gpu_handle_ctrl_cb,
1537 virtio_gpu_handle_cursor_cb,
include/hw/virtio/virtio-gpu.h
+3
@@ -100,6 +100,7 @@ enum virtio_gpu_base_conf_flags {
100 VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
101 VIRTIO_GPU_FLAG_VENUS_ENABLED,
102 VIRTIO_GPU_FLAG_RESOURCE_UUID_ENABLED,
103 + VIRTIO_GPU_FLAG_DRM_ENABLED,
104 };
105
106 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -122,6 +123,8 @@ enum virtio_gpu_base_conf_flags {
123 (_cfg.hostmem > 0)
124 #define virtio_gpu_venus_enabled(_cfg) \
125 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VENUS_ENABLED))
126 +#define virtio_gpu_drm_enabled(_cfg) \
127 + (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DRM_ENABLED))
128
129 struct virtio_gpu_base_conf {
130 uint32_t max_outputs;