#include <panfrost-misc.h>
+#include "util/list.h"
+
struct panfrost_context;
/* Represents a fat pointer for GPU-mapped memory, returned from the transient
};
struct panfrost_bo {
+ /* Must be first for casting */
+ struct list_head link;
+
struct pipe_reference reference;
/* Mapping for the entire object (all levels) */
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();
#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;
/* 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 */