From 3fb60e9cef63f9e0425422e197ec558f3b7bf72b Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 4 Aug 2022 15:41:53 -0700 Subject: [PATCH] freedreno/drm: Add fd_ringbuffer_attach_bo() Which does only the bo bookkeeping and skips all the extra legacy reloc related overhead. Signed-off-by: Rob Clark Part-of: --- src/freedreno/drm/freedreno_ringbuffer.h | 14 ++++++++ src/freedreno/drm/freedreno_ringbuffer_sp.c | 33 +++++++++++++++++++ .../drm/freedreno_ringbuffer_sp_reloc.h | 24 ++------------ 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/freedreno/drm/freedreno_ringbuffer.h b/src/freedreno/drm/freedreno_ringbuffer.h index 903e22d78a3..cd8241f229f 100644 --- a/src/freedreno/drm/freedreno_ringbuffer.h +++ b/src/freedreno/drm/freedreno_ringbuffer.h @@ -126,6 +126,14 @@ struct fd_reloc; struct fd_ringbuffer_funcs { void (*grow)(struct fd_ringbuffer *ring, uint32_t size); + + /** + * Alternative to emit_reloc for the softpin case, where we only need + * to track that the bo is used (and not track all the extra info that + * the kernel would need to do a legacy reloc. + */ + void (*emit_bo)(struct fd_ringbuffer *ring, struct fd_bo *bo); + void (*emit_reloc)(struct fd_ringbuffer *ring, const struct fd_reloc *reloc); uint32_t (*emit_reloc_ring)(struct fd_ringbuffer *ring, struct fd_ringbuffer *target, uint32_t cmd_idx); @@ -216,6 +224,12 @@ struct fd_reloc { /* NOTE: relocs are 2 dwords on a5xx+ */ +static inline void +fd_ringbuffer_attach_bo(struct fd_ringbuffer *ring, struct fd_bo *bo) +{ + ring->funcs->emit_bo(ring, bo); +} + static inline void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc) { diff --git a/src/freedreno/drm/freedreno_ringbuffer_sp.c b/src/freedreno/drm/freedreno_ringbuffer_sp.c index 0c873b73ab9..7df4b395877 100644 --- a/src/freedreno/drm/freedreno_ringbuffer_sp.c +++ b/src/freedreno/drm/freedreno_ringbuffer_sp.c @@ -486,6 +486,35 @@ fd_ringbuffer_references_bo(struct fd_ringbuffer *ring, struct fd_bo *bo) return false; } +static void +fd_ringbuffer_sp_emit_bo_nonobj(struct fd_ringbuffer *ring, struct fd_bo *bo) +{ + assert(!(ring->flags & _FD_RINGBUFFER_OBJECT)); + + struct fd_ringbuffer_sp *fd_ring = to_fd_ringbuffer_sp(ring); + struct fd_submit_sp *fd_submit = to_fd_submit_sp(fd_ring->u.submit); + + fd_submit_append_bo(fd_submit, bo); +} + +static void +fd_ringbuffer_sp_emit_bo_obj(struct fd_ringbuffer *ring, struct fd_bo *bo) +{ + assert(ring->flags & _FD_RINGBUFFER_OBJECT); + + struct fd_ringbuffer_sp *fd_ring = to_fd_ringbuffer_sp(ring); + + /* Avoid emitting duplicate BO references into the list. Ringbuffer + * objects are long-lived, so this saves ongoing work at draw time in + * exchange for a bit at context setup/first draw. And the number of + * relocs per ringbuffer object is fairly small, so the O(n^2) doesn't + * hurt much. + */ + if (!fd_ringbuffer_references_bo(ring, bo)) { + APPEND(&fd_ring->u, reloc_bos, fd_bo_ref(bo)); + } +} + #define PTRSZ 64 #include "freedreno_ringbuffer_sp_reloc.h" #undef PTRSZ @@ -543,6 +572,7 @@ fd_ringbuffer_sp_destroy(struct fd_ringbuffer *ring) static const struct fd_ringbuffer_funcs ring_funcs_nonobj_32 = { .grow = fd_ringbuffer_sp_grow, + .emit_bo = fd_ringbuffer_sp_emit_bo_nonobj, .emit_reloc = fd_ringbuffer_sp_emit_reloc_nonobj_32, .emit_reloc_ring = fd_ringbuffer_sp_emit_reloc_ring_32, .cmd_count = fd_ringbuffer_sp_cmd_count, @@ -552,6 +582,7 @@ static const struct fd_ringbuffer_funcs ring_funcs_nonobj_32 = { static const struct fd_ringbuffer_funcs ring_funcs_obj_32 = { .grow = fd_ringbuffer_sp_grow, + .emit_bo = fd_ringbuffer_sp_emit_bo_obj, .emit_reloc = fd_ringbuffer_sp_emit_reloc_obj_32, .emit_reloc_ring = fd_ringbuffer_sp_emit_reloc_ring_32, .cmd_count = fd_ringbuffer_sp_cmd_count, @@ -560,6 +591,7 @@ static const struct fd_ringbuffer_funcs ring_funcs_obj_32 = { static const struct fd_ringbuffer_funcs ring_funcs_nonobj_64 = { .grow = fd_ringbuffer_sp_grow, + .emit_bo = fd_ringbuffer_sp_emit_bo_nonobj, .emit_reloc = fd_ringbuffer_sp_emit_reloc_nonobj_64, .emit_reloc_ring = fd_ringbuffer_sp_emit_reloc_ring_64, .cmd_count = fd_ringbuffer_sp_cmd_count, @@ -569,6 +601,7 @@ static const struct fd_ringbuffer_funcs ring_funcs_nonobj_64 = { static const struct fd_ringbuffer_funcs ring_funcs_obj_64 = { .grow = fd_ringbuffer_sp_grow, + .emit_bo = fd_ringbuffer_sp_emit_bo_obj, .emit_reloc = fd_ringbuffer_sp_emit_reloc_obj_64, .emit_reloc_ring = fd_ringbuffer_sp_emit_reloc_ring_64, .cmd_count = fd_ringbuffer_sp_cmd_count, diff --git a/src/freedreno/drm/freedreno_ringbuffer_sp_reloc.h b/src/freedreno/drm/freedreno_ringbuffer_sp_reloc.h index 6dfdc31a029..ab0ae6a208b 100644 --- a/src/freedreno/drm/freedreno_ringbuffer_sp_reloc.h +++ b/src/freedreno/drm/freedreno_ringbuffer_sp_reloc.h @@ -44,34 +44,14 @@ static void X(fd_ringbuffer_sp_emit_reloc_nonobj)(struct fd_ringbuffer *ring, const struct fd_reloc *reloc) { X(emit_reloc_common)(ring, reloc); - - assert(!(ring->flags & _FD_RINGBUFFER_OBJECT)); - - struct fd_ringbuffer_sp *fd_ring = to_fd_ringbuffer_sp(ring); - - struct fd_submit_sp *fd_submit = to_fd_submit_sp(fd_ring->u.submit); - - fd_submit_append_bo(fd_submit, reloc->bo); + fd_ringbuffer_sp_emit_bo_nonobj(ring, reloc->bo); } static void X(fd_ringbuffer_sp_emit_reloc_obj)(struct fd_ringbuffer *ring, const struct fd_reloc *reloc) { X(emit_reloc_common)(ring, reloc); - - assert(ring->flags & _FD_RINGBUFFER_OBJECT); - - struct fd_ringbuffer_sp *fd_ring = to_fd_ringbuffer_sp(ring); - - /* Avoid emitting duplicate BO references into the list. Ringbuffer - * objects are long-lived, so this saves ongoing work at draw time in - * exchange for a bit at context setup/first draw. And the number of - * relocs per ringbuffer object is fairly small, so the O(n^2) doesn't - * hurt much. - */ - if (!fd_ringbuffer_references_bo(ring, reloc->bo)) { - APPEND(&fd_ring->u, reloc_bos, fd_bo_ref(reloc->bo)); - } + fd_ringbuffer_sp_emit_bo_obj(ring, reloc->bo); } static uint32_t X(fd_ringbuffer_sp_emit_reloc_ring)(