summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>2019-07-15 08:36:19 -0700
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>2019-07-15 16:12:56 -0700
commit270733fe6af0a726797259f6205c2e6740351e02 (patch)
tree4f0357fea6bd457e8fd84dd475cb1c64e914cd24
parentf3464f798719198df54f0f596b734a3113b5466c (diff)
panfrost: Add BO cache data structure
Linked list of panfrost_bo* nested inside an array of buckets. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
-rw-r--r--src/gallium/drivers/panfrost/pan_allocate.h5
-rw-r--r--src/gallium/drivers/panfrost/pan_screen.c3
-rw-r--r--src/gallium/drivers/panfrost/pan_screen.h16
3 files changed, 24 insertions, 0 deletions
diff --git a/src/gallium/drivers/panfrost/pan_allocate.h b/src/gallium/drivers/panfrost/pan_allocate.h
index 43f69b4aceb..8d925ee38a4 100644
--- a/src/gallium/drivers/panfrost/pan_allocate.h
+++ b/src/gallium/drivers/panfrost/pan_allocate.h
@@ -31,6 +31,8 @@
#include <panfrost-misc.h>
+#include "util/list.h"
+
struct panfrost_context;
/* Represents a fat pointer for GPU-mapped memory, returned from the transient
@@ -42,6 +44,9 @@ struct panfrost_transfer {
};
struct panfrost_bo {
+ /* Must be first for casting */
+ struct list_head link;
+
struct pipe_reference reference;
/* Mapping for the entire object (all levels) */
diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c
index 48ffde0d7b1..43a26856f9b 100644
--- a/src/gallium/drivers/panfrost/pan_screen.c
+++ b/src/gallium/drivers/panfrost/pan_screen.c
@@ -536,6 +536,9 @@ panfrost_create_screen(int fd, struct renderonly *ro)
util_dynarray_init(&screen->transient_bo, screen);
+ for (unsigned i = 0; i < ARRAY_SIZE(screen->bo_cache); ++i)
+ list_inithead(&screen->bo_cache[i]);
+
if (pan_debug & PAN_DBG_TRACE)
pandecode_initialize();
diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h
index 18866db049e..3ea624c8855 100644
--- a/src/gallium/drivers/panfrost/pan_screen.h
+++ b/src/gallium/drivers/panfrost/pan_screen.h
@@ -81,6 +81,16 @@ struct panfrost_screen;
#define MAX_TRANSIENT_SLABS (1024*1024 / TRANSIENT_SLAB_PAGES)
+/* How many power-of-two levels in the BO cache do we want? 2^12
+ * minimum chosen as it is the page size that all allocations are
+ * rounded to */
+
+#define MIN_BO_CACHE_BUCKET (12) /* 2^12 = 4KB */
+#define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */
+
+/* Fencepost problem, hence the off-by-one */
+#define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1)
+
struct panfrost_screen {
struct pipe_screen base;
int fd;
@@ -97,6 +107,12 @@ struct panfrost_screen {
/* Set of free transient BOs */
BITSET_DECLARE(free_transient, MAX_TRANSIENT_SLABS);
+ /* The BO cache is a set of buckets with power-of-two sizes ranging
+ * from 2^12 (4096, the page size) to 2^(12 + MAX_BO_CACHE_BUCKETS).
+ * Each bucket is a linked list of free panfrost_bo objects. */
+
+ struct list_head bo_cache[NR_BO_CACHE_BUCKETS];
+
/* While we're busy building up the job for frame N, the GPU is
* still busy executing frame N-1. So hold a reference to
* yesterjob */