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 <alyssa.rosenzweig@collabora.com>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user