panfrost: Add BO cache data structure
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 15 Jul 2019 15:36:19 +0000 (08:36 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 15 Jul 2019 23:12:56 +0000 (16:12 -0700)
Linked list of panfrost_bo* nested inside an array of buckets.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/pan_allocate.h
src/gallium/drivers/panfrost/pan_screen.c
src/gallium/drivers/panfrost/pan_screen.h

index 43f69b4acebfa9f51fa626c24a030fceaa9967a7..8d925ee38a4c9c2842c1ce02e92631ff2536a7c3 100644 (file)
@@ -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) */
index 48ffde0d7b15f68e51f31ad97d7875d1f2d1ecd2..43a26856f9b1ec373013cde2eef82501944a2887 100644 (file)
@@ -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();
 
index 18866db049edc4b64fc57d4a6e288ff6b2b9c11b..3ea624c8855c073624e28528371ae03df70ce851 100644 (file)
@@ -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 */