summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2020-05-08 14:53:47 -0700
committerMarge Bot <eric+marge@anholt.net>2020-05-14 14:12:15 +0000
commitb1151cd2ffc821a09130f87c2a266b2bfe7b0822 (patch)
treef454bb22fab4288910fedab98d37517feb5c4b6d
parenta6fe0799faf73970ac76e26bac2f7b38195fe1e1 (diff)
freedreno: Avoid duplicate BO relocs in FD_RINGBUFFER_OBJECTs.
For the piglit drawoverhead case, 5/18 of the objects' relocs were duplicated. We can dedupe them at object create time (since objects are long-lived) and avoid repeated relocation work at emit time. nohw drawoverhead program statechange throughput 2.34082% +/- 0.645832% (n=10). Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5020>
-rw-r--r--src/freedreno/drm/msm_ringbuffer_sp.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/freedreno/drm/msm_ringbuffer_sp.c b/src/freedreno/drm/msm_ringbuffer_sp.c
index 6bab90b190a..869c41ddda6 100644
--- a/src/freedreno/drm/msm_ringbuffer_sp.c
+++ b/src/freedreno/drm/msm_ringbuffer_sp.c
@@ -385,9 +385,23 @@ msm_ringbuffer_sp_emit_reloc(struct fd_ringbuffer *ring,
struct fd_pipe *pipe;
if (ring->flags & _FD_RINGBUFFER_OBJECT) {
- unsigned idx = APPEND(&msm_ring->u, reloc_bos);
-
- msm_ring->u.reloc_bos[idx] = fd_bo_ref(reloc->bo);
+ /* 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.
+ */
+ bool found = false;
+ for (int i = 0; i < msm_ring->u.nr_reloc_bos; i++) {
+ if (msm_ring->u.reloc_bos[i] == reloc->bo) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ unsigned idx = APPEND(&msm_ring->u, reloc_bos);
+ msm_ring->u.reloc_bos[idx] = fd_bo_ref(reloc->bo);
+ }
pipe = msm_ring->u.pipe;
} else {