freedreno/drm: Add fd_bo_upload()
authorRob Clark <robdclark@chromium.org>
Wed, 9 Feb 2022 19:02:21 +0000 (11:02 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 25 Mar 2022 02:03:30 +0000 (02:03 +0000)
There are some buffers that we mmap just to write to them a single time.
Add the possibility of the drm backend to provide an alternate upload
path to avoid these mmap's.

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

src/freedreno/drm/freedreno_bo.c
src/freedreno/drm/freedreno_drmif.h
src/freedreno/drm/freedreno_priv.h
src/gallium/drivers/freedreno/ir3/ir3_gallium.c

index 5ae5531..386e777 100644 (file)
@@ -454,16 +454,13 @@ fd_bo_is_cached(struct fd_bo *bo)
    return !!(bo->alloc_flags & FD_BO_CACHED_COHERENT);
 }
 
-void *
-fd_bo_map(struct fd_bo *bo)
+static void *
+bo_map(struct fd_bo *bo)
 {
    if (!bo->map) {
       uint64_t offset;
       int ret;
 
-      if (bo->alloc_flags & FD_BO_NOMAP)
-         return NULL;
-
       ret = bo->funcs->offset(bo, &offset);
       if (ret) {
          return NULL;
@@ -479,6 +476,29 @@ fd_bo_map(struct fd_bo *bo)
    return bo->map;
 }
 
+void *
+fd_bo_map(struct fd_bo *bo)
+{
+   /* don't allow mmap'ing something allocated with FD_BO_NOMAP
+    * for sanity
+    */
+   if (bo->alloc_flags & FD_BO_NOMAP)
+      return NULL;
+
+   return bo_map(bo);
+}
+
+void
+fd_bo_upload(struct fd_bo *bo, void *src, unsigned len)
+{
+   if (bo->funcs->upload) {
+      bo->funcs->upload(bo, src, len);
+      return;
+   }
+
+   memcpy(bo_map(bo), src, len);
+}
+
 /* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */
 int
 fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
index e0e2b5b..6dca865 100644 (file)
@@ -215,6 +215,7 @@ uint32_t fd_bo_handle(struct fd_bo *bo);
 int fd_bo_dmabuf(struct fd_bo *bo);
 uint32_t fd_bo_size(struct fd_bo *bo);
 void *fd_bo_map(struct fd_bo *bo);
+void fd_bo_upload(struct fd_bo *bo, void *src, unsigned len);
 int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op);
 void fd_bo_cpu_fini(struct fd_bo *bo);
 bool fd_bo_is_cached(struct fd_bo *bo);
index 0ccc833..31a5aa9 100644 (file)
@@ -294,6 +294,12 @@ struct fd_bo_funcs {
    uint64_t (*iova)(struct fd_bo *bo);
    void (*set_name)(struct fd_bo *bo, const char *fmt, va_list ap);
    void (*destroy)(struct fd_bo *bo);
+
+   /**
+    * Optional, copy data into bo, falls back to mmap+memcpy.  If not
+    * implemented, it must be possible to mmap all buffers
+    */
+   void (*upload)(struct fd_bo *bo, void *src, unsigned len);
 };
 
 struct fd_bo_fence {
index 482c355..6c42850 100644 (file)
@@ -108,13 +108,13 @@ upload_shader_variant(struct ir3_shader_variant *v)
    assert(!v->bo);
 
    v->bo =
-      fd_bo_new(compiler->dev, v->info.size, 0,
+      fd_bo_new(compiler->dev, v->info.size, FD_BO_NOMAP,
                 "%s:%s", ir3_shader_stage(v), info->name);
 
    /* Always include shaders in kernel crash dumps. */
    fd_bo_mark_for_dump(v->bo);
 
-   memcpy(fd_bo_map(v->bo), v->bin, v->info.size);
+   fd_bo_upload(v->bo, v->bin, v->info.size);
 }
 
 struct ir3_shader_variant *