aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorVasily Khoruzhick <[email protected]>2020-03-03 21:31:51 -0800
committerMarge Bot <[email protected]>2020-03-10 02:41:27 +0000
commit53d6bb9fc633a4d0ad99c25ac4a9ca09f12d87bf (patch)
treee7ec7f7344c7561adeeb1f4a03334f5230b164a6 /src/gallium
parent040a7117c3b404f82a39cf7b2b232a2149ddfeec (diff)
panfrost: split index cache into shared part
Split it into shared part since we're going to re-use it in lima. Reviewed-by: Alyssa Rosenzweig <[email protected]> Reviewed-by: Boris Brezillon <[email protected]> Signed-off-by: Vasily Khoruzhick <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4051>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/panfrost/pan_context.c38
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.c37
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.h24
3 files changed, 9 insertions, 90 deletions
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index efc7c37111e..630f6753fd4 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -29,6 +29,7 @@
#include "pan_bo.h"
#include "pan_context.h"
+#include "pan_minmax_cache.h"
#include "panfrost-quirks.h"
#include "util/macros.h"
@@ -1278,8 +1279,6 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx, const struct pip
needs_indices = false;
}
- uint64_t ht_key = 0;
-
if (!info->has_user_indices) {
/* Only resources can be directly mapped */
panfrost_batch_add_bo(batch, rsrc->bo,
@@ -1289,22 +1288,8 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx, const struct pip
out = rsrc->bo->gpu + offset;
/* Check the cache */
- if (rsrc->index_cache) {
- ht_key = (((uint64_t) info->count) << 32) | info->start;
-
- struct panfrost_minmax_cache *cache = rsrc->index_cache;
-
- for (unsigned i = 0; i < cache->size; ++i) {
- if (cache->keys[i] == ht_key) {
- uint64_t hit = cache->values[i];
-
- *min_index = hit & 0xffffffff;
- *max_index = hit >> 32;
- needs_indices = false;
- break;
- }
- }
- }
+ needs_indices = !panfrost_minmax_cache_get(rsrc->index_cache, info->start, info->count,
+ min_index, max_index);
} else {
/* Otherwise, we need to upload to transient memory */
const uint8_t *ibuf8 = (const uint8_t *) info->index.user;
@@ -1315,20 +1300,9 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx, const struct pip
/* Fallback */
u_vbuf_get_minmax_index(&ctx->base, info, min_index, max_index);
- if (!info->has_user_indices && rsrc->index_cache) {
- struct panfrost_minmax_cache *cache = rsrc->index_cache;
- uint64_t value = (*min_index) | (((uint64_t) *max_index) << 32);
- unsigned index = 0;
-
- if (cache->size == PANFROST_MINMAX_SIZE) {
- index = cache->index++;
- cache->index = cache->index % PANFROST_MINMAX_SIZE;
- } else {
- index = cache->size++;
- }
-
- cache->keys[index] = ht_key;
- cache->values[index] = value;
+ if (!info->has_user_indices) {
+ panfrost_minmax_cache_add(rsrc->index_cache, info->start, info->count,
+ *min_index, *max_index);
}
}
diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index b9d3cf31e3a..ac3e288a0b6 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -536,39 +536,6 @@ panfrost_resource_destroy(struct pipe_screen *screen,
ralloc_free(rsrc);
}
-/* If we've been caching min/max indices and we update the index
- * buffer, that may invalidate the min/max. Check what's been cached vs
- * what we've written, and throw out invalid entries. */
-
-static void
-panfrost_invalidate_index_cache(struct panfrost_resource *rsrc, struct pipe_transfer *transfer)
-{
- struct panfrost_minmax_cache *cache = rsrc->index_cache;
-
- /* Ensure there is a cache to invalidate and a write */
- if (!rsrc->index_cache) return;
- if (!(transfer->usage & PIPE_TRANSFER_WRITE)) return;
-
- unsigned valid_count = 0;
-
- for (unsigned i = 0; i < cache->size; ++i) {
- uint64_t key = cache->keys[i];
-
- uint32_t start = key & 0xffffffff;
- uint32_t count = key >> 32;
-
- /* 1D range intersection */
- bool invalid = MAX2(transfer->box.x, start) < MIN2(transfer->box.x + transfer->box.width, start + count);
- if (!invalid) {
- cache->keys[valid_count] = key;
- cache->values[valid_count] = cache->values[i];
- valid_count++;
- }
- }
-
- cache->size = valid_count;
- cache->index = 0;
-}
static void *
panfrost_transfer_map(struct pipe_context *pctx,
@@ -691,7 +658,7 @@ panfrost_transfer_map(struct pipe_context *pctx,
if ((usage & PIPE_TRANSFER_WRITE) && (usage & PIPE_TRANSFER_MAP_DIRECTLY)) {
rsrc->slices[level].initialized = true;
- panfrost_invalidate_index_cache(rsrc, &transfer->base);
+ panfrost_minmax_cache_invalidate(rsrc->index_cache, &transfer->base);
}
return bo->cpu
@@ -741,7 +708,7 @@ panfrost_transfer_unmap(struct pipe_context *pctx,
transfer->box.x,
transfer->box.x + transfer->box.width);
- panfrost_invalidate_index_cache(prsrc, transfer);
+ panfrost_minmax_cache_invalidate(prsrc->index_cache, transfer);
/* Derefence the resource */
pipe_resource_reference(&transfer->resource, NULL);
diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h
index 2728c7f0aeb..9f8c2890b32 100644
--- a/src/gallium/drivers/panfrost/pan_resource.h
+++ b/src/gallium/drivers/panfrost/pan_resource.h
@@ -29,33 +29,11 @@
#include <panfrost-job.h>
#include "pan_screen.h"
#include "pan_allocate.h"
+#include "pan_minmax_cache.h"
#include "pan_texture.h"
#include "drm-uapi/drm.h"
#include "util/u_range.h"
-/* Index buffer min/max cache. We need to caclculate the min/max for arbitrary
- * slices (start, start + count) of the index buffer at drawtime. As this can
- * be quite expensive, we cache. Conceptually, we just use a hash table mapping
- * the key (start, count) to the value (min, max). In practice, mesa's hash
- * table implementation is higher overhead than we would like and makes
- * handling memory usage a little complicated. So we use this data structure
- * instead. Searching is O(n) to the size, but the size is capped at the
- * PANFROST_MINMAX_SIZE constant (so this is a tradeoff between cache hit/miss
- * ratio and cache search speed). Note that keys are adjacent so we get cache
- * line alignment benefits. Insertion is O(1) and in-order until the cache
- * fills up, after that it evicts the oldest cached value in a ring facilitated
- * by index.
- */
-
-#define PANFROST_MINMAX_SIZE 64
-
-struct panfrost_minmax_cache {
- uint64_t keys[PANFROST_MINMAX_SIZE];
- uint64_t values[PANFROST_MINMAX_SIZE];
- unsigned size;
- unsigned index;
-};
-
struct panfrost_resource {
struct pipe_resource base;
struct {