xref: /aosp_15_r20/external/mesa3d/src/panfrost/vulkan/panvk_mempool.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * © Copyright 2017-2018 Alyssa Rosenzweig
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker  * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  *
23*61046927SAndroid Build Coastguard Worker  */
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker #ifndef __PANVK_POOL_H__
26*61046927SAndroid Build Coastguard Worker #define __PANVK_POOL_H__
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker #include "panvk_priv_bo.h"
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker #include "pan_pool.h"
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker #include "util/list.h"
33*61046927SAndroid Build Coastguard Worker #include "util/simple_mtx.h"
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker struct panvk_bo_pool {
36*61046927SAndroid Build Coastguard Worker    struct list_head free_bos;
37*61046927SAndroid Build Coastguard Worker };
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker static inline void
panvk_bo_pool_init(struct panvk_bo_pool * bo_pool)40*61046927SAndroid Build Coastguard Worker panvk_bo_pool_init(struct panvk_bo_pool *bo_pool)
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker    list_inithead(&bo_pool->free_bos);
43*61046927SAndroid Build Coastguard Worker }
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker void panvk_bo_pool_cleanup(struct panvk_bo_pool *bo_pool);
46*61046927SAndroid Build Coastguard Worker 
47*61046927SAndroid Build Coastguard Worker struct panvk_pool_properties {
48*61046927SAndroid Build Coastguard Worker    /* BO flags to use in the pool */
49*61046927SAndroid Build Coastguard Worker    unsigned create_flags;
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker    /* Allocation granularity. */
52*61046927SAndroid Build Coastguard Worker    size_t slab_size;
53*61046927SAndroid Build Coastguard Worker 
54*61046927SAndroid Build Coastguard Worker    /* Label for created BOs */
55*61046927SAndroid Build Coastguard Worker    const char *label;
56*61046927SAndroid Build Coastguard Worker 
57*61046927SAndroid Build Coastguard Worker    /* When false, BOs allocated by the pool are not retained by the pool
58*61046927SAndroid Build Coastguard Worker     * when they leave the transient_bo field. */
59*61046927SAndroid Build Coastguard Worker    bool owns_bos;
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker    /* If pool is shared and not externally protected, this should be true. */
62*61046927SAndroid Build Coastguard Worker    bool needs_locking;
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker    bool prealloc;
65*61046927SAndroid Build Coastguard Worker };
66*61046927SAndroid Build Coastguard Worker 
67*61046927SAndroid Build Coastguard Worker /* Represents grow-only memory. It may be owned by the batch (OpenGL), or may
68*61046927SAndroid Build Coastguard Worker    be unowned for persistent uploads. */
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker struct panvk_pool {
71*61046927SAndroid Build Coastguard Worker    /* Inherit from pan_pool */
72*61046927SAndroid Build Coastguard Worker    struct pan_pool base;
73*61046927SAndroid Build Coastguard Worker 
74*61046927SAndroid Build Coastguard Worker    /* Parent device for allocation */
75*61046927SAndroid Build Coastguard Worker    struct panvk_device *dev;
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker    /* Pool properties. */
78*61046927SAndroid Build Coastguard Worker    struct panvk_pool_properties props;
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker    /* Before allocating a new BO, check if the BO pool has free BOs.
81*61046927SAndroid Build Coastguard Worker     * When returning BOs, if bo_pool != NULL, return them to this bo_pool.
82*61046927SAndroid Build Coastguard Worker     */
83*61046927SAndroid Build Coastguard Worker    struct panvk_bo_pool *bo_pool;
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker    /* BOs allocated by this pool */
86*61046927SAndroid Build Coastguard Worker    struct list_head bos;
87*61046927SAndroid Build Coastguard Worker    struct list_head big_bos;
88*61046927SAndroid Build Coastguard Worker    unsigned bo_count;
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker    /* Lock used to protect allocation when the pool is shared. */
91*61046927SAndroid Build Coastguard Worker    simple_mtx_t lock;
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker    /* Current transient BO */
94*61046927SAndroid Build Coastguard Worker    struct panvk_priv_bo *transient_bo;
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker    /* Within the topmost transient BO, how much has been used? */
97*61046927SAndroid Build Coastguard Worker    unsigned transient_offset;
98*61046927SAndroid Build Coastguard Worker };
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker static inline struct panvk_pool *
to_panvk_pool(struct pan_pool * pool)101*61046927SAndroid Build Coastguard Worker to_panvk_pool(struct pan_pool *pool)
102*61046927SAndroid Build Coastguard Worker {
103*61046927SAndroid Build Coastguard Worker    return container_of(pool, struct panvk_pool, base);
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker 
106*61046927SAndroid Build Coastguard Worker void panvk_pool_init(struct panvk_pool *pool, struct panvk_device *dev,
107*61046927SAndroid Build Coastguard Worker                      struct panvk_bo_pool *bo_pool,
108*61046927SAndroid Build Coastguard Worker                      const struct panvk_pool_properties *props);
109*61046927SAndroid Build Coastguard Worker 
110*61046927SAndroid Build Coastguard Worker void panvk_pool_reset(struct panvk_pool *pool);
111*61046927SAndroid Build Coastguard Worker 
112*61046927SAndroid Build Coastguard Worker void panvk_pool_cleanup(struct panvk_pool *pool);
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker static inline unsigned
panvk_pool_num_bos(struct panvk_pool * pool)115*61046927SAndroid Build Coastguard Worker panvk_pool_num_bos(struct panvk_pool *pool)
116*61046927SAndroid Build Coastguard Worker {
117*61046927SAndroid Build Coastguard Worker    return pool->bo_count;
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker void panvk_pool_get_bo_handles(struct panvk_pool *pool, uint32_t *handles);
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker struct panvk_priv_mem {
123*61046927SAndroid Build Coastguard Worker    struct panvk_priv_bo *bo;
124*61046927SAndroid Build Coastguard Worker    unsigned offset;
125*61046927SAndroid Build Coastguard Worker };
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker static inline uint64_t
panvk_priv_mem_dev_addr(struct panvk_priv_mem mem)128*61046927SAndroid Build Coastguard Worker panvk_priv_mem_dev_addr(struct panvk_priv_mem mem)
129*61046927SAndroid Build Coastguard Worker {
130*61046927SAndroid Build Coastguard Worker    return mem.bo ? mem.bo->addr.dev + mem.offset : 0;
131*61046927SAndroid Build Coastguard Worker }
132*61046927SAndroid Build Coastguard Worker 
133*61046927SAndroid Build Coastguard Worker static inline void *
panvk_priv_mem_host_addr(struct panvk_priv_mem mem)134*61046927SAndroid Build Coastguard Worker panvk_priv_mem_host_addr(struct panvk_priv_mem mem)
135*61046927SAndroid Build Coastguard Worker {
136*61046927SAndroid Build Coastguard Worker    return mem.bo && mem.bo->addr.host
137*61046927SAndroid Build Coastguard Worker              ? (uint8_t *)mem.bo->addr.host + mem.offset
138*61046927SAndroid Build Coastguard Worker              : NULL;
139*61046927SAndroid Build Coastguard Worker }
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker struct panvk_pool_alloc_info {
142*61046927SAndroid Build Coastguard Worker    size_t size;
143*61046927SAndroid Build Coastguard Worker    unsigned alignment;
144*61046927SAndroid Build Coastguard Worker };
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker static inline struct panvk_pool_alloc_info
panvk_pool_descs_to_alloc_info(const struct pan_desc_alloc_info * descs)147*61046927SAndroid Build Coastguard Worker panvk_pool_descs_to_alloc_info(const struct pan_desc_alloc_info *descs)
148*61046927SAndroid Build Coastguard Worker {
149*61046927SAndroid Build Coastguard Worker    struct panvk_pool_alloc_info alloc_info = {
150*61046927SAndroid Build Coastguard Worker       .alignment = descs[0].align,
151*61046927SAndroid Build Coastguard Worker    };
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; descs[i].size; i++)
154*61046927SAndroid Build Coastguard Worker       alloc_info.size += descs[i].size * descs[i].nelems;
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker    return alloc_info;
157*61046927SAndroid Build Coastguard Worker }
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker struct panvk_priv_mem panvk_pool_alloc_mem(struct panvk_pool *pool,
160*61046927SAndroid Build Coastguard Worker                                            struct panvk_pool_alloc_info info);
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker static inline void
panvk_pool_free_mem(struct panvk_pool * pool,struct panvk_priv_mem mem)163*61046927SAndroid Build Coastguard Worker panvk_pool_free_mem(struct panvk_pool *pool, struct panvk_priv_mem mem)
164*61046927SAndroid Build Coastguard Worker {
165*61046927SAndroid Build Coastguard Worker    if (!pool->props.owns_bos)
166*61046927SAndroid Build Coastguard Worker       panvk_priv_bo_unref(mem.bo);
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker static inline struct panvk_priv_mem
panvk_pool_upload_aligned(struct panvk_pool * pool,const void * data,size_t sz,unsigned alignment)170*61046927SAndroid Build Coastguard Worker panvk_pool_upload_aligned(struct panvk_pool *pool, const void *data, size_t sz,
171*61046927SAndroid Build Coastguard Worker                           unsigned alignment)
172*61046927SAndroid Build Coastguard Worker {
173*61046927SAndroid Build Coastguard Worker    struct panvk_pool_alloc_info info = {
174*61046927SAndroid Build Coastguard Worker       .size = sz,
175*61046927SAndroid Build Coastguard Worker       .alignment = alignment,
176*61046927SAndroid Build Coastguard Worker    };
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker    struct panvk_priv_mem mem = panvk_pool_alloc_mem(pool, info);
179*61046927SAndroid Build Coastguard Worker    memcpy(panvk_priv_mem_host_addr(mem), data, sz);
180*61046927SAndroid Build Coastguard Worker    return mem;
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker static inline struct panvk_priv_mem
panvk_pool_upload(struct panvk_pool * pool,const void * data,size_t sz)184*61046927SAndroid Build Coastguard Worker panvk_pool_upload(struct panvk_pool *pool, const void *data, size_t sz)
185*61046927SAndroid Build Coastguard Worker {
186*61046927SAndroid Build Coastguard Worker    return panvk_pool_upload_aligned(pool, data, sz, sz);
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker #define panvk_pool_alloc_desc(pool, name)                                      \
190*61046927SAndroid Build Coastguard Worker    panvk_pool_alloc_mem(pool, panvk_pool_descs_to_alloc_info(                  \
191*61046927SAndroid Build Coastguard Worker                                  PAN_DESC_AGGREGATE(PAN_DESC(name))))
192*61046927SAndroid Build Coastguard Worker 
193*61046927SAndroid Build Coastguard Worker #define panvk_pool_alloc_desc_array(pool, count, name)                         \
194*61046927SAndroid Build Coastguard Worker    panvk_pool_alloc_mem(pool,                                                  \
195*61046927SAndroid Build Coastguard Worker                         panvk_pool_descs_to_alloc_info(                        \
196*61046927SAndroid Build Coastguard Worker                            PAN_DESC_AGGREGATE(PAN_DESC_ARRAY(count, name))))
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker #define panvk_pool_alloc_desc_aggregate(pool, ...)                             \
199*61046927SAndroid Build Coastguard Worker    panvk_pool_alloc_mem(                                                       \
200*61046927SAndroid Build Coastguard Worker       pool, panvk_pool_descs_to_alloc_info(PAN_DESC_AGGREGATE(__VA_ARGS__)))
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker #endif
203