[PATCH v3 6/6] virtio-gpu: Support DRM native context

Dmitry Osipenko posted 6 patches 1 week, 4 days ago
[PATCH v3 6/6] virtio-gpu: Support DRM native context
Posted by Dmitry Osipenko 1 week, 4 days ago
Add support for DRM native contexts to VirtIO-GPU. DRM context is enabled
using a new virtio-gpu-gl device option "drm=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.

Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
---
 docs/system/devices/virtio-gpu.rst | 11 +++++++++++
 hw/display/virtio-gpu-gl.c         |  2 ++
 hw/display/virtio-gpu-virgl.c      | 22 ++++++++++++++++++++++
 hw/display/virtio-gpu.c            | 15 +++++++++++++++
 include/hw/virtio/virtio-gpu.h     |  3 +++
 5 files changed, 53 insertions(+)

diff --git a/docs/system/devices/virtio-gpu.rst b/docs/system/devices/virtio-gpu.rst
index b7eb0fc0e727..49a75138f7ef 100644
--- a/docs/system/devices/virtio-gpu.rst
+++ b/docs/system/devices/virtio-gpu.rst
@@ -82,6 +82,17 @@ of virtio-gpu host memory window. This is typically between 256M and 8G.
 
 .. _venus: https://gitlab.freedesktop.org/virgl/venus-protocol/
 
+DRM native context is supported since release of `virglrenderer`_ v1.0.0
+using `drm`_ protocol. ``DRM`` virtio-gpu capability set ("capset") requires
+host blob support (``hostmem`` and ``blob`` fields) and should be enabled
+using ``drm`` field. The ``hostmem`` field specifies the size of virtio-gpu
+host memory window. This is typically between 256M and 8G.
+
+.. parsed-literal::
+    -device virtio-gpu-gl,hostmem=8G,blob=on,drm=on
+
+.. _drm: https://gitlab.freedesktop.org/virgl/virglrenderer/-/tree/main/src/drm
+
 virtio-gpu rutabaga
 -------------------
 
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index 53d938f23f20..bd0c0692a5c4 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -159,6 +159,8 @@ static Property virtio_gpu_gl_properties[] = {
                     VIRTIO_GPU_FLAG_STATS_ENABLED, false),
     DEFINE_PROP_BIT("venus", VirtIOGPU, parent_obj.conf.flags,
                     VIRTIO_GPU_FLAG_VENUS_ENABLED, false),
+    DEFINE_PROP_BIT("drm", VirtIOGPU, parent_obj.conf.flags,
+                    VIRTIO_GPU_FLAG_DRM_ENABLED, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 37b40e258398..89ca1878fb7c 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -1232,6 +1232,19 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
     if (virtio_gpu_venus_enabled(g->parent_obj.conf)) {
         flags |= VIRGL_RENDERER_VENUS | VIRGL_RENDERER_RENDER_SERVER;
     }
+    if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
+        flags |= VIRGL_RENDERER_DRM;
+
+        if (!gl->context_fence_enabled) {
+            /*
+             * Virglrenderer skips enabling DRM context support without
+             * enabled async-fence feature. VirtIO-GPU will initialize
+             * successfully, but DRM context won't be available in guest.
+             */
+            error_report("DRM native context requires EGL display");
+            return -EINVAL;
+        }
+    }
 #endif
 
     ret = virgl_renderer_init(g, flags, &virtio_gpu_3d_cbs);
@@ -1294,5 +1307,14 @@ GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g)
         }
     }
 
+    if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
+        virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_DRM,
+                                   &capset_max_ver,
+                                   &capset_max_size);
+        if (capset_max_size) {
+            virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_DRM);
+        }
+    }
+
     return capset_ids;
 }
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index c0570ef8565a..c1acafe6246b 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1492,6 +1492,21 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
 #endif
     }
 
+    if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
+#ifdef VIRGL_VERSION_MAJOR
+    #if VIRGL_VERSION_MAJOR >= 1
+        if (!virtio_gpu_blob_enabled(g->parent_obj.conf) ||
+            !virtio_gpu_hostmem_enabled(g->parent_obj.conf)) {
+            error_setg(errp, "drm requires enabled blob and hostmem options");
+            return;
+        }
+    #else
+        error_setg(errp, "old virglrenderer, drm unsupported");
+        return;
+    #endif
+#endif
+    }
+
     if (!virtio_gpu_base_device_realize(qdev,
                                         virtio_gpu_handle_ctrl_cb,
                                         virtio_gpu_handle_cursor_cb,
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 99cc6286f473..f1799fcb6eee 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -98,6 +98,7 @@ enum virtio_gpu_base_conf_flags {
     VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
     VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
     VIRTIO_GPU_FLAG_VENUS_ENABLED,
+    VIRTIO_GPU_FLAG_DRM_ENABLED,
 };
 
 #define virtio_gpu_virgl_enabled(_cfg) \
@@ -118,6 +119,8 @@ enum virtio_gpu_base_conf_flags {
     (_cfg.hostmem > 0)
 #define virtio_gpu_venus_enabled(_cfg) \
     (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VENUS_ENABLED))
+#define virtio_gpu_drm_enabled(_cfg) \
+    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DRM_ENABLED))
 
 struct virtio_gpu_base_conf {
     uint32_t max_outputs;
-- 
2.47.0
Re: [PATCH v3 6/6] virtio-gpu: Support DRM native context
Posted by Alex Bennée 4 days, 17 hours ago
Dmitry Osipenko <dmitry.osipenko@collabora.com> writes:

> Add support for DRM native contexts to VirtIO-GPU. DRM context is enabled
> using a new virtio-gpu-gl device option "drm=on".

I feel like using "drm" is confusing in this context because drm exists
for the host and guest. What about "native-context" or even
"context=[opengl|vulkan|wayland|native]"?

The GPU command line is already getting complex so now might be the time
to rationalise it.

As an aside can mesa build the intel drivers on non-x86 systems as now I
could potentially pass my native intel context to my emulated aarch64
guests?

>
> 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.
>
> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> ---
>  docs/system/devices/virtio-gpu.rst | 11 +++++++++++
>  hw/display/virtio-gpu-gl.c         |  2 ++
>  hw/display/virtio-gpu-virgl.c      | 22 ++++++++++++++++++++++
>  hw/display/virtio-gpu.c            | 15 +++++++++++++++
>  include/hw/virtio/virtio-gpu.h     |  3 +++
>  5 files changed, 53 insertions(+)
>
> diff --git a/docs/system/devices/virtio-gpu.rst b/docs/system/devices/virtio-gpu.rst
> index b7eb0fc0e727..49a75138f7ef 100644
> --- a/docs/system/devices/virtio-gpu.rst
> +++ b/docs/system/devices/virtio-gpu.rst
> @@ -82,6 +82,17 @@ of virtio-gpu host memory window. This is typically between 256M and 8G.
>  
>  .. _venus: https://gitlab.freedesktop.org/virgl/venus-protocol/
>  
> +DRM native context is supported since release of `virglrenderer`_ v1.0.0
> +using `drm`_ protocol. ``DRM`` virtio-gpu capability set ("capset") requires
> +host blob support (``hostmem`` and ``blob`` fields) and should be enabled
> +using ``drm`` field. The ``hostmem`` field specifies the size of virtio-gpu
> +host memory window. This is typically between 256M and 8G.
> +
> +.. parsed-literal::
> +    -device virtio-gpu-gl,hostmem=8G,blob=on,drm=on
> +
> +.. _drm: https://gitlab.freedesktop.org/virgl/virglrenderer/-/tree/main/src/drm
> +
>  virtio-gpu rutabaga
>  -------------------
>  
> diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
> index 53d938f23f20..bd0c0692a5c4 100644
> --- a/hw/display/virtio-gpu-gl.c
> +++ b/hw/display/virtio-gpu-gl.c
> @@ -159,6 +159,8 @@ static Property virtio_gpu_gl_properties[] = {
>                      VIRTIO_GPU_FLAG_STATS_ENABLED, false),
>      DEFINE_PROP_BIT("venus", VirtIOGPU, parent_obj.conf.flags,
>                      VIRTIO_GPU_FLAG_VENUS_ENABLED, false),
> +    DEFINE_PROP_BIT("drm", VirtIOGPU, parent_obj.conf.flags,
> +                    VIRTIO_GPU_FLAG_DRM_ENABLED, false),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index 37b40e258398..89ca1878fb7c 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -1232,6 +1232,19 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
>      if (virtio_gpu_venus_enabled(g->parent_obj.conf)) {
>          flags |= VIRGL_RENDERER_VENUS | VIRGL_RENDERER_RENDER_SERVER;
>      }
> +    if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
> +        flags |= VIRGL_RENDERER_DRM;
> +
> +        if (!gl->context_fence_enabled) {
> +            /*
> +             * Virglrenderer skips enabling DRM context support without
> +             * enabled async-fence feature. VirtIO-GPU will initialize
> +             * successfully, but DRM context won't be available in guest.
> +             */
> +            error_report("DRM native context requires EGL display");
> +            return -EINVAL;
> +        }
> +    }
>  #endif
>  
>      ret = virgl_renderer_init(g, flags, &virtio_gpu_3d_cbs);
> @@ -1294,5 +1307,14 @@ GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g)
>          }
>      }
>  
> +    if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
> +        virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_DRM,
> +                                   &capset_max_ver,
> +                                   &capset_max_size);
> +        if (capset_max_size) {
> +            virtio_gpu_virgl_add_capset(capset_ids, VIRTIO_GPU_CAPSET_DRM);
> +        }
> +    }
> +
>      return capset_ids;
>  }
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index c0570ef8565a..c1acafe6246b 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -1492,6 +1492,21 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
>  #endif
>      }
>  
> +    if (virtio_gpu_drm_enabled(g->parent_obj.conf)) {
> +#ifdef VIRGL_VERSION_MAJOR
> +    #if VIRGL_VERSION_MAJOR >= 1
> +        if (!virtio_gpu_blob_enabled(g->parent_obj.conf) ||
> +            !virtio_gpu_hostmem_enabled(g->parent_obj.conf)) {
> +            error_setg(errp, "drm requires enabled blob and hostmem options");
> +            return;
> +        }
> +    #else
> +        error_setg(errp, "old virglrenderer, drm unsupported");
> +        return;
> +    #endif
> +#endif
> +    }
> +
>      if (!virtio_gpu_base_device_realize(qdev,
>                                          virtio_gpu_handle_ctrl_cb,
>                                          virtio_gpu_handle_cursor_cb,
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index 99cc6286f473..f1799fcb6eee 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -98,6 +98,7 @@ enum virtio_gpu_base_conf_flags {
>      VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
>      VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
>      VIRTIO_GPU_FLAG_VENUS_ENABLED,
> +    VIRTIO_GPU_FLAG_DRM_ENABLED,
>  };
>  
>  #define virtio_gpu_virgl_enabled(_cfg) \
> @@ -118,6 +119,8 @@ enum virtio_gpu_base_conf_flags {
>      (_cfg.hostmem > 0)
>  #define virtio_gpu_venus_enabled(_cfg) \
>      (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VENUS_ENABLED))
> +#define virtio_gpu_drm_enabled(_cfg) \
> +    (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DRM_ENABLED))
>  
>  struct virtio_gpu_base_conf {
>      uint32_t max_outputs;

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro
Re: [PATCH v3 6/6] virtio-gpu: Support DRM native context
Posted by Dmitry Osipenko 3 days, 11 hours ago
On 10/31/24 13:26, Alex Bennée wrote:
> Dmitry Osipenko <dmitry.osipenko@collabora.com> writes:
> 
>> Add support for DRM native contexts to VirtIO-GPU. DRM context is enabled
>> using a new virtio-gpu-gl device option "drm=on".
> 
> I feel like using "drm" is confusing in this context because drm exists
> for the host and guest. What about "native-context" or even
> "context=[opengl|vulkan|wayland|native]"?
> The GPU command line is already getting complex so now might be the time
> to rationalise it.

Will think on it for v4, thanks.

> As an aside can mesa build the intel drivers on non-x86 systems as now I
> could potentially pass my native intel context to my emulated aarch64
> guests?

In general it should work. Don't know for sure how well Intel Mesa
driver works on ARM, suppose it should work okay because Intel now has
dGPUs. Intel Mesa driver has x86-specific assumptions, though maybe they
are optional for dGPUs. You may try to plug a DG2 card into your AVA
machine and report back :)

-- 
Best regards,
Dmitry

Re: [PATCH v3 6/6] virtio-gpu: Support DRM native context
Posted by Dmitry Osipenko 3 days, 9 hours ago
On 11/1/24 20:13, Dmitry Osipenko wrote:
>> As an aside can mesa build the intel drivers on non-x86 systems as now I
>> could potentially pass my native intel context to my emulated aarch64
>> guests?
> In general it should work. Don't know for sure how well Intel Mesa
> driver works on ARM, suppose it should work okay because Intel now has
> dGPUs. Intel Mesa driver has x86-specific assumptions, though maybe they
> are optional for dGPUs. You may try to plug a DG2 card into your AVA
> machine and report back 🙂

On the other hand, you're right, intel-nctx should work with ARM guest
without KVM. But it should be dead slow without KVM accel, similarly or
worth than it was with Venus when I was testing it on ARM guest.

-- 
Best regards,
Dmitry