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