summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/panfrost/pan_resource.h
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>2020-02-19 10:32:20 -0500
committerMarge Bot <eric+marge@anholt.net>2020-02-27 10:30:48 +0000
commitd385c5840f9f5683e0ca2dcb254b494562838a90 (patch)
treece8bbe41963a63ea8800659e82b4c21e32e7446a /src/gallium/drivers/panfrost/pan_resource.h
parent12db69aa3f6155e9ccb1d783da589ab206dc7239 (diff)
downloadmesa-d385c5840f9f5683e0ca2dcb254b494562838a90.tar.gz
panfrost: Implement index buffer cache
For index bufer resources (not user index buffers), we're able to cache results. In practice, the cache works pretty dang well. It's still important that the min/max computation is efficient (since when the cache misses it'll run at draw-time and we don't want jank), but this can eliminate a lot of computations entirely. We use a custom data structure for caching. Search is O(N) to the size but sizes are capped so it's effectively O(1). Insertion is O(1) with automatic oldest eviction, on the assumption that the oldest results are the least likely to still be useful. We might also experiment with other heuristics based on actual usage later. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3880> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3880>
Diffstat (limited to 'src/gallium/drivers/panfrost/pan_resource.h')
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h
index 7173526023f..2728c7f0aeb 100644
--- a/src/gallium/drivers/panfrost/pan_resource.h
+++ b/src/gallium/drivers/panfrost/pan_resource.h
@@ -33,6 +33,29 @@
#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 {
@@ -60,6 +83,9 @@ struct panfrost_resource {
bool checksummed;
enum pipe_format internal_format;
+
+ /* Cached min/max values for index buffers */
+ struct panfrost_minmax_cache *index_cache;
};
static inline struct panfrost_resource *