diff options
author | Marek Vasut <[email protected]> | 2019-06-03 19:49:14 +0200 |
---|---|---|
committer | Lucas Stach <[email protected]> | 2019-08-14 10:36:04 +0200 |
commit | cf92074277f5d12a6812ead77c5a73419b4cbb83 (patch) | |
tree | 75934b34241880298b3967e91bfbde494ef33d2b /src/etnaviv | |
parent | 23f5f126d5afc7224e0a67398acec7edb3c4941f (diff) |
etnaviv: Use hash table to track BO indexes
Use hash table instead of ad-hoc arrays.
Signed-off-by: Marek Vasut <[email protected]>
Reviewed-by: Lucas Stach <[email protected]>
Diffstat (limited to 'src/etnaviv')
-rw-r--r-- | src/etnaviv/drm/etnaviv_bo.c | 6 | ||||
-rw-r--r-- | src/etnaviv/drm/etnaviv_cmd_stream.c | 23 | ||||
-rw-r--r-- | src/etnaviv/drm/etnaviv_priv.h | 12 |
3 files changed, 26 insertions, 15 deletions
diff --git a/src/etnaviv/drm/etnaviv_bo.c b/src/etnaviv/drm/etnaviv_bo.c index 2b1fbbbc3c7..6436fea4162 100644 --- a/src/etnaviv/drm/etnaviv_bo.c +++ b/src/etnaviv/drm/etnaviv_bo.c @@ -47,14 +47,14 @@ void _etna_bo_del(struct etna_bo *bo) if (bo->map) os_munmap(bo->map, bo->size); - if (bo->name) - _mesa_hash_table_remove_key(bo->dev->name_table, &bo->name); - if (bo->handle) { struct drm_gem_close req = { .handle = bo->handle, }; + if (bo->name) + _mesa_hash_table_remove_key(bo->dev->name_table, &bo->name); + _mesa_hash_table_remove_key(bo->dev->handle_table, &bo->handle); drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req); } diff --git a/src/etnaviv/drm/etnaviv_cmd_stream.c b/src/etnaviv/drm/etnaviv_cmd_stream.c index e591df297a3..894ad603c08 100644 --- a/src/etnaviv/drm/etnaviv_cmd_stream.c +++ b/src/etnaviv/drm/etnaviv_cmd_stream.c @@ -153,14 +153,20 @@ static uint32_t bo2idx(struct etna_cmd_stream *stream, struct etna_bo *bo, if (bo->current_stream == stream) { idx = bo->idx; } else { - /* slow-path: */ - for (idx = 0; idx < priv->nr_bos; idx++) - if (priv->bos[idx] == bo) - break; - if (idx == priv->nr_bos) { - /* not found */ + void *val; + + if (!priv->bo_table) + priv->bo_table = drmHashCreate(); + + if (!drmHashLookup(priv->bo_table, bo->handle, &val)) { + /* found */ + idx = (uint32_t)(uintptr_t)val; + } else { idx = append_bo(stream, bo); + val = (void *)(uintptr_t)idx; + drmHashInsert(priv->bo_table, bo->handle, val); } + bo->current_stream = stream; bo->idx = idx; } @@ -217,6 +223,11 @@ static void flush(struct etna_cmd_stream *stream, int in_fence_fd, etna_bo_del(bo); } + if (priv->bo_table) { + drmHashDestroy(priv->bo_table); + priv->bo_table = NULL; + } + if (out_fence_fd) *out_fence_fd = req.fence_fd; } diff --git a/src/etnaviv/drm/etnaviv_priv.h b/src/etnaviv/drm/etnaviv_priv.h index 527cee30dc3..d8f053771e9 100644 --- a/src/etnaviv/drm/etnaviv_priv.h +++ b/src/etnaviv/drm/etnaviv_priv.h @@ -99,12 +99,10 @@ struct etna_bo { uint64_t offset; /* offset to mmap() */ int refcnt; - /* in the common case, a bo won't be referenced by more than a single - * command stream. So to avoid looping over all the bo's in the - * reloc table to find the idx of a bo that might already be in the - * table, we cache the idx in the bo. But in order to detect the - * slow-path where bo is ref'd in multiple streams, we also must track - * the current_stream for which the idx is valid. See bo2idx(). + /* + * To avoid excess hashtable lookups, cache the stream this bo was + * last emitted on (since that will probably also be the next ring + * it is emitted on). */ struct etna_cmd_stream *current_stream; uint32_t idx; @@ -154,6 +152,8 @@ struct etna_cmd_stream_priv { /* notify callback if buffer reset happened */ void (*reset_notify)(struct etna_cmd_stream *stream, void *priv); void *reset_notify_priv; + + void *bo_table; }; struct etna_perfmon { |