1 /**************************************************************************
2 *
3 * Copyright 2018-2019 Alyssa Rosenzweig
4 * Copyright 2018-2019 Collabora, Ltd.
5 * Copyright © 2015 Intel Corporation
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 **************************************************************************/
29
30 #ifndef PAN_DEVICE_H
31 #define PAN_DEVICE_H
32
33 #include <xf86drm.h>
34 #include "renderonly/renderonly.h"
35 #include "util/bitset.h"
36 #include "util/list.h"
37 #include "util/sparse_array.h"
38 #include "util/timespec.h"
39 #include "util/u_dynarray.h"
40
41 #include "panfrost/util/pan_ir.h"
42 #include "pan_blend.h"
43 #include "pan_fb_preload.h"
44 #include "pan_indirect_dispatch.h"
45 #include "pan_pool.h"
46 #include "pan_props.h"
47 #include "pan_util.h"
48
49 #include "kmod/pan_kmod.h"
50
51 #include <genxml/gen_macros.h>
52
53 #if defined(__cplusplus)
54 extern "C" {
55 #endif
56
57 /* Always reserve the lower 32MB */
58 #define PAN_VA_USER_START 0x2000000ull
59
60 /* Max address space size allowed */
61 #define PAN_VA_USER_END (1ull << 48ull)
62
63 /* Driver limits */
64 #define PAN_MAX_CONST_BUFFERS 16
65
66 /* TODO: Mali hardware can texture up to 64k textures, but the
67 * Gallium interface limits us to 32k at the moment */
68 #define PAN_MAX_MIP_LEVELS 16
69
70 #define PAN_MAX_TEXEL_BUFFER_ELEMENTS 65536
71
72 /* How many power-of-two levels in the BO cache do we want? 2^12
73 * minimum chosen as it is the page size that all allocations are
74 * rounded to */
75
76 #define MIN_BO_CACHE_BUCKET (12) /* 2^12 = 4KB */
77 #define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */
78
79 /* Fencepost problem, hence the off-by-one */
80 #define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1)
81
82 struct panfrost_device {
83 /* For ralloc */
84 void *memctx;
85
86 /* Kmod objects. */
87 struct {
88 /* The pan_kmod_dev object backing this device. */
89 struct pan_kmod_dev *dev;
90
91 /* Cached pan_kmod_dev_props properties queried at device create time. */
92 struct pan_kmod_dev_props props;
93
94 /* VM attached to this device. */
95 struct pan_kmod_vm *vm;
96 } kmod;
97
98 /* For pandecode */
99 struct pandecode_context *decode_ctx;
100
101 /* Properties of the GPU in use */
102 unsigned arch;
103
104 /* Number of shader cores */
105 unsigned core_count;
106
107 /* Range of core IDs, equal to the maximum core ID + 1. Satisfies
108 * core_id_range >= core_count.
109 */
110 unsigned core_id_range;
111
112 /* Maximum tilebuffer size in bytes for optimal performance. */
113 unsigned optimal_tib_size;
114
115 unsigned thread_tls_alloc;
116 struct panfrost_tiler_features tiler_features;
117 const struct panfrost_model *model;
118 bool has_afbc;
119 bool has_afrc;
120
121 /* Table of formats, indexed by a PIPE format */
122 const struct panfrost_format *formats;
123 const struct pan_blendable_format *blendable_formats;
124
125 /* Bitmask of supported compressed texture formats */
126 uint32_t compressed_formats;
127
128 /* debug flags, see pan_util.h how to interpret */
129 unsigned debug;
130
131 struct renderonly *ro;
132
133 pthread_mutex_t bo_map_lock;
134 struct util_sparse_array bo_map;
135
136 struct {
137 pthread_mutex_t lock;
138
139 /* List containing all cached BOs sorted in LRU (Least
140 * Recently Used) order. This allows us to quickly evict BOs
141 * that are more than 1 second old.
142 */
143 struct list_head lru;
144
145 /* The BO cache is a set of buckets with power-of-two sizes
146 * ranging from 2^12 (4096, the page size) to
147 * 2^(12 + MAX_BO_CACHE_BUCKETS).
148 * Each bucket is a linked list of free panfrost_bo objects. */
149
150 struct list_head buckets[NR_BO_CACHE_BUCKETS];
151 } bo_cache;
152
153 struct pan_fb_preload_cache fb_preload_cache;
154 struct pan_blend_shader_cache blend_shaders;
155 struct pan_indirect_dispatch_meta indirect_dispatch;
156
157 /* Tiler heap shared across all tiler jobs, allocated against the
158 * device since there's only a single tiler. Since this is invisible to
159 * the CPU, it's okay for multiple contexts to reference it
160 * simultaneously; by keeping on the device struct, we eliminate a
161 * costly per-context allocation. */
162
163 struct panfrost_bo *tiler_heap;
164
165 /* The tiler heap is shared by all contexts, and is written by tiler
166 * jobs and read by fragment job. We need to ensure that a
167 * vertex/tiler job chain from one context is not inserted between
168 * the vertex/tiler and fragment job of another context, otherwise
169 * we end up with tiler heap corruption.
170 */
171 pthread_mutex_t submit_lock;
172
173 /* Sample positions are preloaded into a write-once constant buffer,
174 * such that they can be referenced fore free later. Needed
175 * unconditionally on Bifrost, and useful for sharing with Midgard */
176
177 struct panfrost_bo *sample_positions;
178 };
179
180 static inline int
panfrost_device_fd(const struct panfrost_device * dev)181 panfrost_device_fd(const struct panfrost_device *dev)
182 {
183 return dev->kmod.dev->fd;
184 }
185
186 static inline uint32_t
panfrost_device_gpu_id(const struct panfrost_device * dev)187 panfrost_device_gpu_id(const struct panfrost_device *dev)
188 {
189 return dev->kmod.props.gpu_prod_id;
190 }
191
192 static inline uint32_t
panfrost_device_gpu_rev(const struct panfrost_device * dev)193 panfrost_device_gpu_rev(const struct panfrost_device *dev)
194 {
195 return dev->kmod.props.gpu_revision;
196 }
197
198 static inline int
panfrost_device_kmod_version_major(const struct panfrost_device * dev)199 panfrost_device_kmod_version_major(const struct panfrost_device *dev)
200 {
201 return dev->kmod.dev->driver.version.major;
202 }
203
204 static inline int
panfrost_device_kmod_version_minor(const struct panfrost_device * dev)205 panfrost_device_kmod_version_minor(const struct panfrost_device *dev)
206 {
207 return dev->kmod.dev->driver.version.minor;
208 }
209
210 int panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev);
211
212 void panfrost_close_device(struct panfrost_device *dev);
213
214 bool panfrost_supports_compressed_format(struct panfrost_device *dev,
215 unsigned texfeat_bit);
216
217 static inline struct panfrost_bo *
pan_lookup_bo(struct panfrost_device * dev,uint32_t gem_handle)218 pan_lookup_bo(struct panfrost_device *dev, uint32_t gem_handle)
219 {
220 return (struct panfrost_bo *)util_sparse_array_get(&dev->bo_map, gem_handle);
221 }
222
223 static inline bool
pan_is_bifrost(const struct panfrost_device * dev)224 pan_is_bifrost(const struct panfrost_device *dev)
225 {
226 return dev->arch >= 6 && dev->arch <= 7;
227 }
228
229 static inline uint64_t
pan_gpu_time_to_ns(struct panfrost_device * dev,uint64_t gpu_time)230 pan_gpu_time_to_ns(struct panfrost_device *dev, uint64_t gpu_time)
231 {
232 assert(dev->kmod.props.timestamp_frequency > 0);
233 return (gpu_time * NSEC_PER_SEC) / dev->kmod.props.timestamp_frequency;
234 }
235
236 #if defined(__cplusplus)
237 } // extern "C"
238 #endif
239
240 #endif
241