xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/pool.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2017-2018 Alyssa Rosenzweig
3  * SPDX-License-Identifier: MIT
4  *
5  */
6 
7 #pragma once
8 
9 #include <stddef.h>
10 #include "asahi/genxml/agx_pack.h"
11 #include "agx_bo.h"
12 
13 #include "util/u_dynarray.h"
14 
15 /* Represents a pool of memory that can only grow, used to allocate objects
16  * with the same lifetime as the pool itself. In OpenGL, a pool is owned by the
17  * batch for transient structures. In Vulkan, it may be owned by e.g. the
18  * command pool */
19 
20 struct agx_pool {
21    /* Parent device for allocation */
22    struct agx_device *dev;
23 
24    /* BOs allocated by this pool */
25    struct util_dynarray bos;
26 
27    /* Current transient BO */
28    struct agx_bo *transient_bo;
29 
30    /* Within the topmost transient BO, how much has been used? */
31    unsigned transient_offset;
32 
33    /* BO flags to use in the pool */
34    unsigned create_flags;
35 };
36 
37 void agx_pool_init(struct agx_pool *pool, struct agx_device *dev,
38                    unsigned create_flags, bool prealloc);
39 
40 void agx_pool_cleanup(struct agx_pool *pool);
41 
42 static inline unsigned
agx_pool_num_bos(struct agx_pool * pool)43 agx_pool_num_bos(struct agx_pool *pool)
44 {
45    return util_dynarray_num_elements(&pool->bos, struct agx_bo *);
46 }
47 
48 void agx_pool_get_bo_handles(struct agx_pool *pool, uint32_t *handles);
49 
50 /* Represents a fat pointer for GPU-mapped memory, returned from the transient
51  * allocator and not used for much else */
52 
53 struct agx_ptr agx_pool_alloc_aligned_with_bo(struct agx_pool *pool, size_t sz,
54                                               unsigned alignment,
55                                               struct agx_bo **bo);
56 
57 static inline struct agx_ptr
agx_pool_alloc_aligned(struct agx_pool * pool,size_t sz,unsigned alignment)58 agx_pool_alloc_aligned(struct agx_pool *pool, size_t sz, unsigned alignment)
59 {
60    return agx_pool_alloc_aligned_with_bo(pool, sz, alignment, NULL);
61 }
62 
63 uint64_t agx_pool_upload(struct agx_pool *pool, const void *data, size_t sz);
64 
65 uint64_t agx_pool_upload_aligned_with_bo(struct agx_pool *pool,
66                                          const void *data, size_t sz,
67                                          unsigned alignment,
68                                          struct agx_bo **bo);
69 
70 static inline uint64_t
agx_pool_upload_aligned(struct agx_pool * pool,const void * data,size_t sz,unsigned alignment)71 agx_pool_upload_aligned(struct agx_pool *pool, const void *data, size_t sz,
72                         unsigned alignment)
73 {
74    return agx_pool_upload_aligned_with_bo(pool, data, sz, alignment, NULL);
75 }
76 
77 struct agx_desc_alloc_info {
78    unsigned size;
79    unsigned align;
80    unsigned nelems;
81 };
82 
83 #define AGX_DESC_ARRAY(count, name)                                            \
84    {                                                                           \
85       .size = MALI_##name##_LENGTH, .align = MALI_##name##_ALIGN,              \
86       .nelems = count,                                                         \
87    }
88 
89 #define AGX_DESC(name) AGX_DESC_ARRAY(1, name)
90 
91 #define AGX_DESC_AGGREGATE(...)                                                \
92    (struct agx_desc_alloc_info[])                                              \
93    {                                                                           \
94       __VA_ARGS__, {0},                                                        \
95    }
96 
97 static inline struct agx_ptr
agx_pool_alloc_descs(struct agx_pool * pool,const struct agx_desc_alloc_info * descs)98 agx_pool_alloc_descs(struct agx_pool *pool,
99                      const struct agx_desc_alloc_info *descs)
100 {
101    unsigned size = 0;
102    unsigned align = descs[0].align;
103 
104    for (unsigned i = 0; descs[i].size; i++) {
105       assert(!(size & (descs[i].align - 1)));
106       size += descs[i].size * descs[i].nelems;
107    }
108 
109    return agx_pool_alloc_aligned(pool, size, align);
110 }
111 
112 #define agx_pool_alloc_desc(pool, name)                                        \
113    agx_pool_alloc_descs(pool, AGX_DESC_AGGREGATE(AGX_DESC(name)))
114 
115 #define agx_pool_alloc_desc_array(pool, count, name)                           \
116    agx_pool_alloc_descs(pool, AGX_DESC_AGGREGATE(AGX_DESC_ARRAY(count, name)))
117 
118 #define agx_pool_alloc_desc_aggregate(pool, ...)                               \
119    agx_pool_alloc_descs(pool, AGX_DESC_AGGREGATE(__VA_ARGS__))
120