1 /*
2 * © Copyright 2017-2018 Alyssa Rosenzweig
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 */
24
25 #ifndef __PAN_POOL_H__
26 #define __PAN_POOL_H__
27
28 #include <stddef.h>
29 #include <genxml/gen_macros.h>
30
31 #include "util/u_dynarray.h"
32
33 struct panfrost_ptr {
34 /* CPU address */
35 void *cpu;
36
37 /* GPU address */
38 mali_ptr gpu;
39 };
40
41 /* Represents grow-only memory. */
42
43 struct pan_pool {
44 /* Minimum size for allocated BOs. */
45 size_t slab_size;
46 };
47
48 static inline void
pan_pool_init(struct pan_pool * pool,size_t slab_size)49 pan_pool_init(struct pan_pool *pool, size_t slab_size)
50 {
51 pool->slab_size = slab_size;
52 }
53
54 /* Represents a fat pointer for GPU-mapped memory, returned from the transient
55 * allocator and not used for much else */
56
57 struct panfrost_ptr pan_pool_alloc_aligned(struct pan_pool *pool, size_t sz,
58 unsigned alignment);
59
60 #define PAN_POOL_ALLOCATOR(pool_subclass, alloc_func) \
61 struct panfrost_ptr pan_pool_alloc_aligned(struct pan_pool *p, size_t sz, \
62 unsigned alignment) \
63 { \
64 pool_subclass *pool = container_of(p, pool_subclass, base); \
65 return alloc_func(pool, sz, alignment); \
66 }
67
68 static inline mali_ptr
pan_pool_upload_aligned(struct pan_pool * pool,const void * data,size_t sz,unsigned alignment)69 pan_pool_upload_aligned(struct pan_pool *pool, const void *data, size_t sz,
70 unsigned alignment)
71 {
72 struct panfrost_ptr transfer = pan_pool_alloc_aligned(pool, sz, alignment);
73 memcpy(transfer.cpu, data, sz);
74 return transfer.gpu;
75 }
76
77 static inline mali_ptr
pan_pool_upload(struct pan_pool * pool,const void * data,size_t sz)78 pan_pool_upload(struct pan_pool *pool, const void *data, size_t sz)
79 {
80 return pan_pool_upload_aligned(pool, data, sz, sz);
81 }
82
83 struct pan_desc_alloc_info {
84 unsigned size;
85 unsigned align;
86 unsigned nelems;
87 };
88
89 #define PAN_DESC_ARRAY(count, name) \
90 { \
91 .size = pan_size(name), .align = pan_alignment(name), .nelems = count, \
92 }
93
94 #define PAN_DESC(name) PAN_DESC_ARRAY(1, name)
95
96 #define PAN_DESC_AGGREGATE(...) \
97 (struct pan_desc_alloc_info[]) \
98 { \
99 __VA_ARGS__, {0}, \
100 }
101
102 static inline struct panfrost_ptr
pan_pool_alloc_descs(struct pan_pool * pool,const struct pan_desc_alloc_info * descs)103 pan_pool_alloc_descs(struct pan_pool *pool,
104 const struct pan_desc_alloc_info *descs)
105 {
106 unsigned size = 0;
107 unsigned align = descs[0].align;
108
109 for (unsigned i = 0; descs[i].size; i++) {
110 assert(!(size & (descs[i].align - 1)));
111 size += descs[i].size * descs[i].nelems;
112 }
113
114 return pan_pool_alloc_aligned(pool, size, align);
115 }
116
117 #define pan_pool_alloc_desc(pool, name) \
118 pan_pool_alloc_descs(pool, PAN_DESC_AGGREGATE(PAN_DESC(name)))
119
120 #define pan_pool_alloc_desc_array(pool, count, name) \
121 pan_pool_alloc_descs(pool, PAN_DESC_AGGREGATE(PAN_DESC_ARRAY(count, name)))
122
123 #define pan_pool_alloc_desc_aggregate(pool, ...) \
124 pan_pool_alloc_descs(pool, PAN_DESC_AGGREGATE(__VA_ARGS__))
125
126 #endif
127