panfrost: Add panfrost_transient_bo array
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 11 Jul 2019 17:34:40 +0000 (10:34 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 12 Jul 2019 22:31:47 +0000 (15:31 -0700)
We would like transient allocations to occur on the screen (borrowed by
the batch) rather than on the context. Add fields to track this.

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

index c77bd59e2b5b95a8e89a4aec9fff7b3664963b1b..73da1ec5ed055e8ea975bf27b509219a1a238269 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * © Copyright 2018 Alyssa Rosenzweig
+ * Copyright (C) 2019 Collabora, Ltd.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -55,6 +56,23 @@ panfrost_allocate_chunk(struct panfrost_context *ctx, size_t size, unsigned heap
         return transfer;
 }
 
+/* Allocate a new transient slab */
+
+static struct panfrost_bo *
+panfrost_create_slab(struct panfrost_screen *screen)
+{
+        /* Allocate a new slab on the screen */
+
+        struct panfrost_bo **new =
+                util_dynarray_grow(&screen->transient_bo,
+                                struct panfrost_bo *, 1);
+
+        struct panfrost_bo *alloc = panfrost_drm_create_bo(screen, TRANSIENT_SLAB_SIZE, 0);
+
+        *new = alloc;
+        return alloc;
+}
+
 /* Transient command stream pooling: command stream uploads try to simply copy
  * into whereever we left off. If there isn't space, we allocate a new entry
  * into the pool and copy there */
index cfcee5743b9b809b2bf5256fcfdcfd7cd10b887c..599ef8a82e7da8193e1dd6e40ff144134423d313 100644 (file)
@@ -529,6 +529,8 @@ panfrost_create_screen(int fd, struct renderonly *ro)
                 return NULL;
         }
 
+        util_dynarray_init(&screen->transient_bo, screen);
+
         if (pan_debug & PAN_DBG_TRACE)
                 pandecode_initialize();
 
index bf64b8b40e0e10a72e1fec20c6d5956f31aae309..ab39da6d2a181c6a4d55fa773254da099b1d284b 100644 (file)
@@ -32,6 +32,8 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_defines.h"
 #include "renderonly/renderonly.h"
+#include "util/u_dynarray.h"
+#include "util/bitset.h"
 
 #include <panfrost-misc.h>
 #include "pan_allocate.h"
@@ -46,6 +48,22 @@ struct panfrost_screen;
 #define PAN_ALLOCATE_INVISIBLE (1 << 2)
 #define PAN_ALLOCATE_COHERENT_LOCAL (1 << 3)
 
+/* Transient slab size. This is a balance between fragmentation against cache
+ * locality and ease of bookkeeping */
+
+#define TRANSIENT_SLAB_PAGES (32) /* 128kb */
+#define TRANSIENT_SLAB_SIZE (4096 * TRANSIENT_SLAB_PAGES)
+
+/* Maximum number of transient slabs so we don't need dynamic arrays. Most
+ * interesting Mali boards are 4GB RAM max, so if the entire RAM was filled
+ * with transient slabs, you could never exceed (4GB / TRANSIENT_SLAB_SIZE)
+ * allocations anyway. By capping, we can use a fixed-size bitset for tracking
+ * free slabs, eliminating quite a bit of complexity. We can pack the free
+ * state of 8 slabs into a single byte, so for 128kb transient slabs the bitset
+ * occupies a cheap 4kb of memory */
+
+#define MAX_TRANSIENT_SLABS (1024*1024 / TRANSIENT_SLAB_PAGES)
+
 struct panfrost_screen {
         struct pipe_screen base;
         int fd;
@@ -56,6 +74,15 @@ struct panfrost_screen {
         /* Memory management is based on subdividing slabs with AMD's allocator */
         struct pb_slabs slabs;
 
+        /* Transient memory management is based on borrowing fixed-size slabs
+         * off the screen (loaning them out to the batch). Dynamic array
+         * container of panfrost_bo */
+
+        struct util_dynarray transient_bo;
+
+        /* Set of free transient BOs */
+        BITSET_DECLARE(free_transient, MAX_TRANSIENT_SLABS);
+
         /* 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 */