xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/pool.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2018 Alyssa Rosenzweig
3*61046927SAndroid Build Coastguard Worker  * Copyright 2019 Collabora, Ltd.
4*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker  *
6*61046927SAndroid Build Coastguard Worker  */
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include "pool.h"
9*61046927SAndroid Build Coastguard Worker #include "agx_bo.h"
10*61046927SAndroid Build Coastguard Worker #include "agx_device.h"
11*61046927SAndroid Build Coastguard Worker 
12*61046927SAndroid Build Coastguard Worker /* Transient command stream pooling: command stream uploads try to simply copy
13*61046927SAndroid Build Coastguard Worker  * into wherever we left off. If there isn't space, we allocate a new entry
14*61046927SAndroid Build Coastguard Worker  * into the pool and copy there */
15*61046927SAndroid Build Coastguard Worker 
16*61046927SAndroid Build Coastguard Worker #define POOL_SLAB_SIZE (256 * 1024)
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker static struct agx_bo *
agx_pool_alloc_backing(struct agx_pool * pool,size_t bo_sz)19*61046927SAndroid Build Coastguard Worker agx_pool_alloc_backing(struct agx_pool *pool, size_t bo_sz)
20*61046927SAndroid Build Coastguard Worker {
21*61046927SAndroid Build Coastguard Worker    struct agx_bo *bo =
22*61046927SAndroid Build Coastguard Worker       agx_bo_create(pool->dev, bo_sz, 0, pool->create_flags, "Pool");
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker    util_dynarray_append(&pool->bos, struct agx_bo *, bo);
25*61046927SAndroid Build Coastguard Worker    pool->transient_bo = bo;
26*61046927SAndroid Build Coastguard Worker    pool->transient_offset = 0;
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker    return bo;
29*61046927SAndroid Build Coastguard Worker }
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker void
agx_pool_init(struct agx_pool * pool,struct agx_device * dev,unsigned create_flags,bool prealloc)32*61046927SAndroid Build Coastguard Worker agx_pool_init(struct agx_pool *pool, struct agx_device *dev,
33*61046927SAndroid Build Coastguard Worker               unsigned create_flags, bool prealloc)
34*61046927SAndroid Build Coastguard Worker {
35*61046927SAndroid Build Coastguard Worker    memset(pool, 0, sizeof(*pool));
36*61046927SAndroid Build Coastguard Worker    pool->dev = dev;
37*61046927SAndroid Build Coastguard Worker    pool->create_flags = create_flags;
38*61046927SAndroid Build Coastguard Worker    util_dynarray_init(&pool->bos, NULL);
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker    if (prealloc)
41*61046927SAndroid Build Coastguard Worker       agx_pool_alloc_backing(pool, POOL_SLAB_SIZE);
42*61046927SAndroid Build Coastguard Worker }
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker void
agx_pool_cleanup(struct agx_pool * pool)45*61046927SAndroid Build Coastguard Worker agx_pool_cleanup(struct agx_pool *pool)
46*61046927SAndroid Build Coastguard Worker {
47*61046927SAndroid Build Coastguard Worker    util_dynarray_foreach(&pool->bos, struct agx_bo *, bo) {
48*61046927SAndroid Build Coastguard Worker       agx_bo_unreference(pool->dev, *bo);
49*61046927SAndroid Build Coastguard Worker    }
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker    util_dynarray_fini(&pool->bos);
52*61046927SAndroid Build Coastguard Worker }
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker void
agx_pool_get_bo_handles(struct agx_pool * pool,uint32_t * handles)55*61046927SAndroid Build Coastguard Worker agx_pool_get_bo_handles(struct agx_pool *pool, uint32_t *handles)
56*61046927SAndroid Build Coastguard Worker {
57*61046927SAndroid Build Coastguard Worker    unsigned idx = 0;
58*61046927SAndroid Build Coastguard Worker    util_dynarray_foreach(&pool->bos, struct agx_bo *, bo) {
59*61046927SAndroid Build Coastguard Worker       handles[idx++] = (*bo)->handle;
60*61046927SAndroid Build Coastguard Worker    }
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker struct agx_ptr
agx_pool_alloc_aligned_with_bo(struct agx_pool * pool,size_t sz,unsigned alignment,struct agx_bo ** out_bo)64*61046927SAndroid Build Coastguard Worker agx_pool_alloc_aligned_with_bo(struct agx_pool *pool, size_t sz,
65*61046927SAndroid Build Coastguard Worker                                unsigned alignment, struct agx_bo **out_bo)
66*61046927SAndroid Build Coastguard Worker {
67*61046927SAndroid Build Coastguard Worker    assert(alignment == util_next_power_of_two(alignment));
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker    /* Find or create a suitable BO */
70*61046927SAndroid Build Coastguard Worker    struct agx_bo *bo = pool->transient_bo;
71*61046927SAndroid Build Coastguard Worker    unsigned offset = ALIGN_POT(pool->transient_offset, alignment);
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    /* If we don't fit, allocate a new backing */
74*61046927SAndroid Build Coastguard Worker    if (unlikely(bo == NULL || (offset + sz) >= POOL_SLAB_SIZE)) {
75*61046927SAndroid Build Coastguard Worker       bo = agx_pool_alloc_backing(pool,
76*61046927SAndroid Build Coastguard Worker                                   ALIGN_POT(MAX2(POOL_SLAB_SIZE, sz), 4096));
77*61046927SAndroid Build Coastguard Worker       offset = 0;
78*61046927SAndroid Build Coastguard Worker    }
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker    pool->transient_offset = offset + sz;
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker    struct agx_ptr ret = {
83*61046927SAndroid Build Coastguard Worker       .cpu = bo->map + offset,
84*61046927SAndroid Build Coastguard Worker       .gpu = bo->va->addr + offset,
85*61046927SAndroid Build Coastguard Worker    };
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker    if (out_bo)
88*61046927SAndroid Build Coastguard Worker       *out_bo = bo;
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker    return ret;
91*61046927SAndroid Build Coastguard Worker }
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker uint64_t
agx_pool_upload(struct agx_pool * pool,const void * data,size_t sz)94*61046927SAndroid Build Coastguard Worker agx_pool_upload(struct agx_pool *pool, const void *data, size_t sz)
95*61046927SAndroid Build Coastguard Worker {
96*61046927SAndroid Build Coastguard Worker    return agx_pool_upload_aligned(pool, data, sz, util_next_power_of_two(sz));
97*61046927SAndroid Build Coastguard Worker }
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker uint64_t
agx_pool_upload_aligned_with_bo(struct agx_pool * pool,const void * data,size_t sz,unsigned alignment,struct agx_bo ** bo)100*61046927SAndroid Build Coastguard Worker agx_pool_upload_aligned_with_bo(struct agx_pool *pool, const void *data,
101*61046927SAndroid Build Coastguard Worker                                 size_t sz, unsigned alignment,
102*61046927SAndroid Build Coastguard Worker                                 struct agx_bo **bo)
103*61046927SAndroid Build Coastguard Worker {
104*61046927SAndroid Build Coastguard Worker    struct agx_ptr transfer =
105*61046927SAndroid Build Coastguard Worker       agx_pool_alloc_aligned_with_bo(pool, sz, alignment, bo);
106*61046927SAndroid Build Coastguard Worker    memcpy(transfer.cpu, data, sz);
107*61046927SAndroid Build Coastguard Worker    return transfer.gpu;
108*61046927SAndroid Build Coastguard Worker }
109