diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-07-11 10:34:40 -0700 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-07-12 15:31:47 -0700 |
commit | 330cd057adb04a7e579e8e9ba7e3952b448928a8 (patch) | |
tree | 0a3c664e3df97ed50626f1a689003511d427cd38 /src/gallium | |
parent | 718ebfa2259cb50efc05541af205842b6630cf43 (diff) |
panfrost: Add panfrost_transient_bo array
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/panfrost/pan_allocate.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_screen.h | 27 |
3 files changed, 47 insertions, 0 deletions
diff --git a/src/gallium/drivers/panfrost/pan_allocate.c b/src/gallium/drivers/panfrost/pan_allocate.c index c77bd59e2b5..73da1ec5ed0 100644 --- a/src/gallium/drivers/panfrost/pan_allocate.c +++ b/src/gallium/drivers/panfrost/pan_allocate.c @@ -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 */ diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index cfcee5743b9..599ef8a82e7 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -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(); diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h index bf64b8b40e0..ab39da6d2a1 100644 --- a/src/gallium/drivers/panfrost/pan_screen.h +++ b/src/gallium/drivers/panfrost/pan_screen.h @@ -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 */ |