1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * © Copyright 2017-2018 Alyssa Rosenzweig
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#ifndef __AGX_POOL_H__
26bf215546Sopenharmony_ci#define __AGX_POOL_H__
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include <stddef.h>
29bf215546Sopenharmony_ci#include "asahi/lib/agx_pack.h"
30bf215546Sopenharmony_ci#include "agx_bo.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "util/u_dynarray.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci/* Represents a pool of memory that can only grow, used to allocate objects
35bf215546Sopenharmony_ci * with the same lifetime as the pool itself. In OpenGL, a pool is owned by the
36bf215546Sopenharmony_ci * batch for transient structures. In Vulkan, it may be owned by e.g. the
37bf215546Sopenharmony_ci * command pool */
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_cistruct agx_pool {
40bf215546Sopenharmony_ci   /* Parent device for allocation */
41bf215546Sopenharmony_ci   struct agx_device *dev;
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci   /* BOs allocated by this pool */
44bf215546Sopenharmony_ci   struct util_dynarray bos;
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   /* Current transient BO */
47bf215546Sopenharmony_ci   struct agx_bo *transient_bo;
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci   /* Within the topmost transient BO, how much has been used? */
50bf215546Sopenharmony_ci   unsigned transient_offset;
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   /* BO flags to use in the pool */
53bf215546Sopenharmony_ci   unsigned create_flags;
54bf215546Sopenharmony_ci};
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_civoid
57bf215546Sopenharmony_ciagx_pool_init(struct agx_pool *pool, struct agx_device *dev,
58bf215546Sopenharmony_ci      unsigned create_flags, bool prealloc);
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_civoid
61bf215546Sopenharmony_ciagx_pool_cleanup(struct agx_pool *pool);
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_cistatic inline unsigned
64bf215546Sopenharmony_ciagx_pool_num_bos(struct agx_pool *pool)
65bf215546Sopenharmony_ci{
66bf215546Sopenharmony_ci   return util_dynarray_num_elements(&pool->bos, struct agx_bo *);
67bf215546Sopenharmony_ci}
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_civoid
70bf215546Sopenharmony_ciagx_pool_get_bo_handles(struct agx_pool *pool, uint32_t *handles);
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci/* Represents a fat pointer for GPU-mapped memory, returned from the transient
73bf215546Sopenharmony_ci * allocator and not used for much else */
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_cistruct agx_ptr
76bf215546Sopenharmony_ciagx_pool_alloc_aligned(struct agx_pool *pool, size_t sz, unsigned alignment);
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ciuint64_t
79bf215546Sopenharmony_ciagx_pool_upload(struct agx_pool *pool, const void *data, size_t sz);
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ciuint64_t
82bf215546Sopenharmony_ciagx_pool_upload_aligned(struct agx_pool *pool, const void *data, size_t sz, unsigned alignment);
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_cistruct agx_desc_alloc_info {
85bf215546Sopenharmony_ci   unsigned size;
86bf215546Sopenharmony_ci   unsigned align;
87bf215546Sopenharmony_ci   unsigned nelems;
88bf215546Sopenharmony_ci};
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci#define AGX_DESC_ARRAY(count, name) \
91bf215546Sopenharmony_ci        { \
92bf215546Sopenharmony_ci                .size = MALI_ ## name ## _LENGTH, \
93bf215546Sopenharmony_ci                .align = MALI_ ## name ## _ALIGN, \
94bf215546Sopenharmony_ci                .nelems = count, \
95bf215546Sopenharmony_ci        }
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci#define AGX_DESC(name) AGX_DESC_ARRAY(1, name)
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci#define AGX_DESC_AGGREGATE(...) \
100bf215546Sopenharmony_ci        (struct agx_desc_alloc_info[]) { \
101bf215546Sopenharmony_ci                __VA_ARGS__, \
102bf215546Sopenharmony_ci                { 0 }, \
103bf215546Sopenharmony_ci        }
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_cistatic inline struct agx_ptr
106bf215546Sopenharmony_ciagx_pool_alloc_descs(struct agx_pool *pool,
107bf215546Sopenharmony_ci                          const struct agx_desc_alloc_info *descs)
108bf215546Sopenharmony_ci{
109bf215546Sopenharmony_ci   unsigned size = 0;
110bf215546Sopenharmony_ci   unsigned align = descs[0].align;
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   for (unsigned i = 0; descs[i].size; i++) {
113bf215546Sopenharmony_ci      assert(!(size & (descs[i].align - 1)));
114bf215546Sopenharmony_ci      size += descs[i].size * descs[i].nelems;
115bf215546Sopenharmony_ci   }
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   return agx_pool_alloc_aligned(pool, size, align);
118bf215546Sopenharmony_ci}
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci#define agx_pool_alloc_desc(pool, name) \
121bf215546Sopenharmony_ci        agx_pool_alloc_descs(pool, AGX_DESC_AGGREGATE(AGX_DESC(name)))
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci#define agx_pool_alloc_desc_array(pool, count, name) \
124bf215546Sopenharmony_ci        agx_pool_alloc_descs(pool, AGX_DESC_AGGREGATE(AGX_DESC_ARRAY(count, name)))
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci#define agx_pool_alloc_desc_aggregate(pool, ...) \
127bf215546Sopenharmony_ci        agx_pool_alloc_descs(pool, AGX_DESC_AGGREGATE(__VA_ARGS__))
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci#endif
130