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>
This commit is contained in:
Eric Anholt 2020-05-08 14:53:47 -07:00 committed by Marge Bot
parent a6fe0799fa
commit b1151cd2ff
1 changed files with 17 additions and 3 deletions

View File

@ -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 {