Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/etnaviv/drm/etnaviv_priv.h
4564 views
1
/*
2
* Copyright (C) 2014-2015 Etnaviv Project
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
* Authors:
24
* Christian Gmeiner <[email protected]>
25
*/
26
27
#ifndef ETNAVIV_PRIV_H_
28
#define ETNAVIV_PRIV_H_
29
30
#include <stdlib.h>
31
#include <errno.h>
32
#include <string.h>
33
#include <unistd.h>
34
#include <errno.h>
35
#include <fcntl.h>
36
#include <sys/ioctl.h>
37
#include <stdio.h>
38
#include <assert.h>
39
40
#include <xf86drm.h>
41
42
#include "util/list.h"
43
#include "util/macros.h"
44
#include "util/simple_mtx.h"
45
#include "util/timespec.h"
46
#include "util/u_atomic.h"
47
#include "util/u_debug.h"
48
#include "util/vma.h"
49
50
#include "etnaviv_drmif.h"
51
#include "drm-uapi/etnaviv_drm.h"
52
53
extern simple_mtx_t etna_drm_table_lock;
54
55
struct etna_bo_bucket {
56
uint32_t size;
57
struct list_head list;
58
};
59
60
struct etna_bo_cache {
61
struct etna_bo_bucket cache_bucket[14 * 4];
62
unsigned num_buckets;
63
time_t time;
64
};
65
66
struct etna_device {
67
int fd;
68
int refcnt;
69
70
/* tables to keep track of bo's, to avoid "evil-twin" etna_bo objects:
71
*
72
* handle_table: maps handle to etna_bo
73
* name_table: maps flink name to etna_bo
74
*
75
* We end up needing two tables, because DRM_IOCTL_GEM_OPEN always
76
* returns a new handle. So we need to figure out if the bo is already
77
* open in the process first, before calling gem-open.
78
*/
79
void *handle_table, *name_table;
80
81
struct etna_bo_cache bo_cache;
82
83
int use_softpin;
84
struct util_vma_heap address_space;
85
86
int closefd; /* call close(fd) upon destruction */
87
};
88
89
void etna_bo_cache_init(struct etna_bo_cache *cache);
90
void etna_bo_cache_cleanup(struct etna_bo_cache *cache, time_t time);
91
struct etna_bo *etna_bo_cache_alloc(struct etna_bo_cache *cache,
92
uint32_t *size, uint32_t flags);
93
int etna_bo_cache_free(struct etna_bo_cache *cache, struct etna_bo *bo);
94
95
/* for where @etna_drm_table_lock is already held: */
96
void etna_device_del_locked(struct etna_device *dev);
97
98
/* a GEM buffer object allocated from the DRM device */
99
struct etna_bo {
100
struct etna_device *dev;
101
void *map; /* userspace mmap'ing (if there is one) */
102
uint32_t size;
103
uint32_t handle;
104
uint32_t flags;
105
uint32_t name; /* flink global handle (DRI2 name) */
106
uint64_t offset; /* offset to mmap() */
107
uint32_t va; /* GPU virtual address */
108
int refcnt;
109
110
/*
111
* To avoid excess hashtable lookups, cache the stream this bo was
112
* last emitted on (since that will probably also be the next ring
113
* it is emitted on).
114
*/
115
struct etna_cmd_stream *current_stream;
116
uint32_t idx;
117
118
int reuse;
119
struct list_head list; /* bucket-list entry */
120
time_t free_time; /* time when added to bucket-list */
121
};
122
123
struct etna_gpu {
124
struct etna_device *dev;
125
uint32_t core;
126
uint32_t model;
127
uint32_t revision;
128
};
129
130
struct etna_pipe {
131
enum etna_pipe_id id;
132
struct etna_gpu *gpu;
133
};
134
135
struct etna_cmd_stream_priv {
136
struct etna_cmd_stream base;
137
struct etna_pipe *pipe;
138
139
uint32_t last_timestamp;
140
141
/* submit ioctl related tables: */
142
struct {
143
/* bo's table: */
144
struct drm_etnaviv_gem_submit_bo *bos;
145
uint32_t nr_bos, max_bos;
146
147
/* reloc's table: */
148
struct drm_etnaviv_gem_submit_reloc *relocs;
149
uint32_t nr_relocs, max_relocs;
150
151
/* perf's table: */
152
struct drm_etnaviv_gem_submit_pmr *pmrs;
153
uint32_t nr_pmrs, max_pmrs;
154
} submit;
155
156
/* should have matching entries in submit.bos: */
157
struct etna_bo **bos;
158
uint32_t nr_bos, max_bos;
159
160
/* notify callback if buffer reset happened */
161
void (*force_flush)(struct etna_cmd_stream *stream, void *priv);
162
void *force_flush_priv;
163
164
void *bo_table;
165
};
166
167
struct etna_perfmon {
168
struct list_head domains;
169
struct etna_pipe *pipe;
170
};
171
172
struct etna_perfmon_domain
173
{
174
struct list_head head;
175
struct list_head signals;
176
uint8_t id;
177
char name[64];
178
};
179
180
struct etna_perfmon_signal
181
{
182
struct list_head head;
183
struct etna_perfmon_domain *domain;
184
uint8_t signal;
185
char name[64];
186
};
187
188
#define ALIGN(v,a) (((v) + (a) - 1) & ~((a) - 1))
189
190
#define enable_debug 0 /* TODO make dynamic */
191
192
#define INFO_MSG(fmt, ...) \
193
do { debug_printf("[I] "fmt " (%s:%d)\n", \
194
##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
195
#define DEBUG_MSG(fmt, ...) \
196
do if (enable_debug) { debug_printf("[D] "fmt " (%s:%d)\n", \
197
##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
198
#define WARN_MSG(fmt, ...) \
199
do { debug_printf("[W] "fmt " (%s:%d)\n", \
200
##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
201
#define ERROR_MSG(fmt, ...) \
202
do { debug_printf("[E] " fmt " (%s:%d)\n", \
203
##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0)
204
205
#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
206
207
static inline void get_abs_timeout(struct drm_etnaviv_timespec *tv, uint64_t ns)
208
{
209
struct timespec t;
210
clock_gettime(CLOCK_MONOTONIC, &t);
211
tv->tv_sec = t.tv_sec + ns / NSEC_PER_SEC;
212
tv->tv_nsec = t.tv_nsec + ns % NSEC_PER_SEC;
213
if (tv->tv_nsec >= NSEC_PER_SEC) {
214
tv->tv_nsec -= NSEC_PER_SEC;
215
tv->tv_sec++;
216
}
217
}
218
219
#if HAVE_VALGRIND
220
# include <memcheck.h>
221
222
/*
223
* For tracking the backing memory (if valgrind enabled, we force a mmap
224
* for the purposes of tracking)
225
*/
226
static inline void VG_BO_ALLOC(struct etna_bo *bo)
227
{
228
if (bo && RUNNING_ON_VALGRIND) {
229
VALGRIND_MALLOCLIKE_BLOCK(etna_bo_map(bo), bo->size, 0, 1);
230
}
231
}
232
233
static inline void VG_BO_FREE(struct etna_bo *bo)
234
{
235
VALGRIND_FREELIKE_BLOCK(bo->map, 0);
236
}
237
238
/*
239
* For tracking bo structs that are in the buffer-cache, so that valgrind
240
* doesn't attribute ownership to the first one to allocate the recycled
241
* bo.
242
*
243
* Note that the list_head in etna_bo is used to track the buffers in cache
244
* so disable error reporting on the range while they are in cache so
245
* valgrind doesn't squawk about list traversal.
246
*
247
*/
248
static inline void VG_BO_RELEASE(struct etna_bo *bo)
249
{
250
if (RUNNING_ON_VALGRIND) {
251
VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, sizeof(*bo));
252
VALGRIND_MAKE_MEM_NOACCESS(bo, sizeof(*bo));
253
VALGRIND_FREELIKE_BLOCK(bo->map, 0);
254
}
255
}
256
static inline void VG_BO_OBTAIN(struct etna_bo *bo)
257
{
258
if (RUNNING_ON_VALGRIND) {
259
VALGRIND_MAKE_MEM_DEFINED(bo, sizeof(*bo));
260
VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, sizeof(*bo));
261
VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1);
262
}
263
}
264
#else
265
static inline void VG_BO_ALLOC(struct etna_bo *bo) {}
266
static inline void VG_BO_FREE(struct etna_bo *bo) {}
267
static inline void VG_BO_RELEASE(struct etna_bo *bo) {}
268
static inline void VG_BO_OBTAIN(struct etna_bo *bo) {}
269
#endif
270
271
#endif /* ETNAVIV_PRIV_H_ */
272
273