From 9bcc98325602a47e30fcac7016c60748f2ba0c19 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 9 Feb 2022 11:02:21 -0800 Subject: [PATCH] freedreno/drm: Add fd_bo_upload() 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 Part-of: --- src/freedreno/drm/freedreno_bo.c | 30 ++++++++++++++++++++----- src/freedreno/drm/freedreno_drmif.h | 1 + src/freedreno/drm/freedreno_priv.h | 6 +++++ src/gallium/drivers/freedreno/ir3/ir3_gallium.c | 4 ++-- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/freedreno/drm/freedreno_bo.c b/src/freedreno/drm/freedreno_bo.c index 5ae5531..386e777 100644 --- a/src/freedreno/drm/freedreno_bo.c +++ b/src/freedreno/drm/freedreno_bo.c @@ -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) diff --git a/src/freedreno/drm/freedreno_drmif.h b/src/freedreno/drm/freedreno_drmif.h index e0e2b5b..6dca865 100644 --- a/src/freedreno/drm/freedreno_drmif.h +++ b/src/freedreno/drm/freedreno_drmif.h @@ -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); diff --git a/src/freedreno/drm/freedreno_priv.h b/src/freedreno/drm/freedreno_priv.h index 0ccc833..31a5aa9 100644 --- a/src/freedreno/drm/freedreno_priv.h +++ b/src/freedreno/drm/freedreno_priv.h @@ -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 { diff --git a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c index 482c355..6c42850 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c @@ -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 * -- 2.7.4