Mesa (main): freedreno/drm/virtio: Support ring_idx

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 27 23:33:33 UTC 2022


Module: Mesa
Branch: main
Commit: ae01c27ac0d1222d547383594603e43a8971e803
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ae01c27ac0d1222d547383594603e43a8971e803

Author: Rob Clark <robdclark at chromium.org>
Date:   Tue Apr  5 09:21:14 2022 -0700

freedreno/drm/virtio: Support ring_idx

ring_idx zero is the CPU ring, others map to the priority level, as each
priority level for a given drm_file on the host kernel side maps to a
single fence timeline.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16086>

---

 include/drm-uapi/virtgpu_drm.h               |  1 -
 src/freedreno/drm/virtio/virtio_device.c     | 19 +++++++++++++++----
 src/freedreno/drm/virtio/virtio_pipe.c       | 11 +++++------
 src/freedreno/drm/virtio/virtio_priv.h       |  3 ++-
 src/freedreno/drm/virtio/virtio_ringbuffer.c |  3 ++-
 5 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/include/drm-uapi/virtgpu_drm.h b/include/drm-uapi/virtgpu_drm.h
index edead0e3b8d..a13e20cc66b 100644
--- a/include/drm-uapi/virtgpu_drm.h
+++ b/include/drm-uapi/virtgpu_drm.h
@@ -163,7 +163,6 @@ struct drm_virtgpu_resource_create_blob {
 #define VIRTGPU_BLOB_FLAG_USE_MAPPABLE     0x0001
 #define VIRTGPU_BLOB_FLAG_USE_SHAREABLE    0x0002
 #define VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004
-#define VIRTGPU_BLOB_FLAG_USE_INTERNAL     0x0008   /* not-mappable, not-shareable */
 	/* zero is invalid blob_mem */
 	__u32 blob_mem;
 	__u32 blob_flags;
diff --git a/src/freedreno/drm/virtio/virtio_device.c b/src/freedreno/drm/virtio/virtio_device.c
index 1c748dbf5ed..3a75d2d8b7a 100644
--- a/src/freedreno/drm/virtio/virtio_device.c
+++ b/src/freedreno/drm/virtio/virtio_device.c
@@ -25,6 +25,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include "util/libsync.h"
 #include "util/u_process.h"
 
 #include "virtio_priv.h"
@@ -63,6 +64,7 @@ set_context(int fd)
 {
    struct drm_virtgpu_context_set_param params[] = {
          { VIRTGPU_CONTEXT_PARAM_CAPSET_ID, VIRGL_RENDERER_CAPSET_DRM },
+         { VIRTGPU_CONTEXT_PARAM_NUM_RINGS, 64 },
    };
    struct drm_virtgpu_context_init args = {
       .num_params = ARRAY_SIZE(params),
@@ -219,10 +221,13 @@ virtio_alloc_rsp(struct fd_device *dev, struct msm_ccmd_req *req, uint32_t sz)
  * Helper for "execbuf" ioctl.. note that in virtgpu execbuf is just
  * a generic "send commands to host", not necessarily specific to
  * cmdstream execution.
+ *
+ * Note that ring_idx 0 is the "CPU ring", ie. for synchronizing btwn
+ * guest and host CPU.
  */
 int
 virtio_execbuf_fenced(struct fd_device *dev, struct msm_ccmd_req *req,
-                      int in_fence_fd, int *out_fence_fd)
+                      int in_fence_fd, int *out_fence_fd, int ring_idx)
 {
    struct virtio_device *virtio_dev = to_virtio_device(dev);
 
@@ -232,10 +237,12 @@ virtio_execbuf_fenced(struct fd_device *dev, struct msm_ccmd_req *req,
 #define COND(bool, val) ((bool) ? (val) : 0)
    struct drm_virtgpu_execbuffer eb = {
          .flags = COND(out_fence_fd, VIRTGPU_EXECBUF_FENCE_FD_OUT) |
-                  COND(in_fence_fd != -1, VIRTGPU_EXECBUF_FENCE_FD_IN),
+                  COND(in_fence_fd != -1, VIRTGPU_EXECBUF_FENCE_FD_IN) |
+                  VIRTGPU_EXECBUF_RING_IDX,
          .fence_fd = in_fence_fd,
          .size  = req->len,
          .command = VOID2U64(req),
+         .ring_idx = ring_idx,
    };
 
    int ret = drmIoctl(dev->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &eb);
@@ -254,13 +261,17 @@ virtio_execbuf_fenced(struct fd_device *dev, struct msm_ccmd_req *req,
 int
 virtio_execbuf(struct fd_device *dev, struct msm_ccmd_req *req, bool sync)
 {
-   int ret = virtio_execbuf_fenced(dev, req, -1, NULL);
+   int fence_fd;
+   int ret = virtio_execbuf_fenced(dev, req, -1, sync ? &fence_fd : NULL, 0);
 
    if (ret)
       return ret;
 
-   if (sync)
+   if (sync) {
+      sync_wait(fence_fd, -1);
+      close(fence_fd);
       virtio_host_sync(dev, req);
+   }
 
    return 0;
 }
diff --git a/src/freedreno/drm/virtio/virtio_pipe.c b/src/freedreno/drm/virtio/virtio_pipe.c
index 16995551bd0..3bb312347d7 100644
--- a/src/freedreno/drm/virtio/virtio_pipe.c
+++ b/src/freedreno/drm/virtio/virtio_pipe.c
@@ -95,11 +95,7 @@ virtio_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
    case FD_TIMESTAMP:
       return query_param(pipe, MSM_PARAM_TIMESTAMP, value);
    case FD_NR_RINGS:
-      /* TODO need to not rely on host egl ctx for fence if
-       * we want to support multiple priority levels
-       */
-      return 1;
-//      return query_param(pipe, MSM_PARAM_NR_RINGS, value);
+      return query_param(pipe, MSM_PARAM_NR_RINGS, value);
    case FD_CTX_FAULTS:
       return query_queue_param(pipe, MSM_SUBMITQUEUE_PARAM_FAULTS, value);
    case FD_GLOBAL_FAULTS:
@@ -138,6 +134,8 @@ out:
 static int
 open_submitqueue(struct fd_pipe *pipe, uint32_t prio)
 {
+   struct virtio_pipe *virtio_pipe = to_virtio_pipe(pipe);
+
    struct drm_msm_submitqueue req = {
       .flags = 0,
       .prio = prio,
@@ -155,7 +153,8 @@ open_submitqueue(struct fd_pipe *pipe, uint32_t prio)
       return ret;
    }
 
-   to_virtio_pipe(pipe)->queue_id = req.id;
+   virtio_pipe->queue_id = req.id;
+   virtio_pipe->ring_idx = req.prio + 1;
 
    return 0;
 }
diff --git a/src/freedreno/drm/virtio/virtio_priv.h b/src/freedreno/drm/virtio/virtio_priv.h
index c3caea78589..9193f092731 100644
--- a/src/freedreno/drm/virtio/virtio_priv.h
+++ b/src/freedreno/drm/virtio/virtio_priv.h
@@ -66,6 +66,7 @@ struct virtio_pipe {
    uint64_t gmem_base;
    uint32_t gmem;
    uint32_t queue_id;
+   uint32_t ring_idx;
    struct slab_parent_pool ring_pool;
 
    /**
@@ -113,7 +114,7 @@ struct fd_bo *virtio_bo_from_handle(struct fd_device *dev, uint32_t size,
  */
 void *virtio_alloc_rsp(struct fd_device *dev, struct msm_ccmd_req *hdr, uint32_t sz);
 int virtio_execbuf_fenced(struct fd_device *dev, struct msm_ccmd_req *req,
-                          int in_fence_fd, int *out_fence_fd);
+                          int in_fence_fd, int *out_fence_fd, int ring_idx);
 int virtio_execbuf(struct fd_device *dev, struct msm_ccmd_req *req, bool sync);
 void virtio_host_sync(struct fd_device *dev, const struct msm_ccmd_req *req);
 int virtio_simple_ioctl(struct fd_device *dev, unsigned cmd, void *req);
diff --git a/src/freedreno/drm/virtio/virtio_ringbuffer.c b/src/freedreno/drm/virtio/virtio_ringbuffer.c
index 9d5ee1d6af1..6c6aa06e7b3 100644
--- a/src/freedreno/drm/virtio/virtio_ringbuffer.c
+++ b/src/freedreno/drm/virtio/virtio_ringbuffer.c
@@ -166,7 +166,8 @@ flush_submit_list(struct list_head *submit_list)
       req->flags |= MSM_SUBMIT_NO_IMPLICIT;
    }
 
-   virtio_execbuf_fenced(dev, &req->hdr, fd_submit->in_fence_fd, out_fence_fd);
+   virtio_execbuf_fenced(dev, &req->hdr, fd_submit->in_fence_fd, out_fence_fd,
+                         virtio_pipe->ring_idx);
 
    free(req);
 



More information about the mesa-commit mailing list