summaryrefslogtreecommitdiffstats
path: root/src/etnaviv
diff options
context:
space:
mode:
authorMarek Vasut <[email protected]>2019-06-03 19:49:14 +0200
committerLucas Stach <[email protected]>2019-08-14 10:36:04 +0200
commitcf92074277f5d12a6812ead77c5a73419b4cbb83 (patch)
tree75934b34241880298b3967e91bfbde494ef33d2b /src/etnaviv
parent23f5f126d5afc7224e0a67398acec7edb3c4941f (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.c6
-rw-r--r--src/etnaviv/drm/etnaviv_cmd_stream.c23
-rw-r--r--src/etnaviv/drm/etnaviv_priv.h12
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 {