Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/winsys/i915/drm/i915_drm_buffer.c
4566 views
1
#include "frontend/drm_driver.h"
2
#include "i915_drm_winsys.h"
3
#include "util/u_memory.h"
4
5
#include "drm-uapi/i915_drm.h"
6
7
static char *i915_drm_type_to_name(enum i915_winsys_buffer_type type)
8
{
9
char *name;
10
11
if (type == I915_NEW_TEXTURE) {
12
name = "gallium3d_texture";
13
} else if (type == I915_NEW_VERTEX) {
14
name = "gallium3d_vertex";
15
} else if (type == I915_NEW_SCANOUT) {
16
name = "gallium3d_scanout";
17
} else {
18
assert(0);
19
name = "gallium3d_unknown";
20
}
21
22
return name;
23
}
24
25
static struct i915_winsys_buffer *
26
i915_drm_buffer_create(struct i915_winsys *iws,
27
unsigned size,
28
enum i915_winsys_buffer_type type)
29
{
30
struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
31
struct i915_drm_winsys *idws = i915_drm_winsys(iws);
32
33
if (!buf)
34
return NULL;
35
36
buf->magic = 0xDEAD1337;
37
buf->flinked = false;
38
buf->flink = 0;
39
40
buf->bo = drm_intel_bo_alloc(idws->gem_manager,
41
i915_drm_type_to_name(type), size, 0);
42
43
if (!buf->bo)
44
goto err;
45
46
return (struct i915_winsys_buffer *)buf;
47
48
err:
49
assert(0);
50
FREE(buf);
51
return NULL;
52
}
53
54
static struct i915_winsys_buffer *
55
i915_drm_buffer_create_tiled(struct i915_winsys *iws,
56
unsigned *stride, unsigned height,
57
enum i915_winsys_buffer_tile *tiling,
58
enum i915_winsys_buffer_type type)
59
{
60
struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
61
struct i915_drm_winsys *idws = i915_drm_winsys(iws);
62
unsigned long pitch = 0;
63
uint32_t tiling_mode = *tiling;
64
65
if (!buf)
66
return NULL;
67
68
buf->magic = 0xDEAD1337;
69
buf->flinked = false;
70
buf->flink = 0;
71
72
buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager,
73
i915_drm_type_to_name(type),
74
*stride, height, 1,
75
&tiling_mode, &pitch, 0);
76
77
if (!buf->bo)
78
goto err;
79
80
*stride = pitch;
81
*tiling = tiling_mode;
82
return (struct i915_winsys_buffer *)buf;
83
84
err:
85
assert(0);
86
FREE(buf);
87
return NULL;
88
}
89
90
static struct i915_winsys_buffer *
91
i915_drm_buffer_from_handle(struct i915_winsys *iws,
92
struct winsys_handle *whandle,
93
unsigned height,
94
enum i915_winsys_buffer_tile *tiling,
95
unsigned *stride)
96
{
97
struct i915_drm_winsys *idws = i915_drm_winsys(iws);
98
struct i915_drm_buffer *buf;
99
uint32_t tile = 0, swizzle = 0;
100
101
if ((whandle->type != WINSYS_HANDLE_TYPE_SHARED) && (whandle->type != WINSYS_HANDLE_TYPE_FD))
102
return NULL;
103
104
if (whandle->offset != 0)
105
return NULL;
106
107
buf = CALLOC_STRUCT(i915_drm_buffer);
108
if (!buf)
109
return NULL;
110
111
buf->magic = 0xDEAD1337;
112
113
if (whandle->type == WINSYS_HANDLE_TYPE_SHARED)
114
buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle);
115
else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
116
int fd = (int) whandle->handle;
117
buf->bo = drm_intel_bo_gem_create_from_prime(idws->gem_manager, fd, height * whandle->stride);
118
}
119
120
buf->flinked = true;
121
buf->flink = whandle->handle;
122
123
if (!buf->bo)
124
goto err;
125
126
drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
127
128
*stride = whandle->stride;
129
*tiling = tile;
130
131
return (struct i915_winsys_buffer *)buf;
132
133
err:
134
FREE(buf);
135
return NULL;
136
}
137
138
static bool
139
i915_drm_buffer_get_handle(struct i915_winsys *iws,
140
struct i915_winsys_buffer *buffer,
141
struct winsys_handle *whandle,
142
unsigned stride)
143
{
144
struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
145
146
if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
147
if (!buf->flinked) {
148
if (drm_intel_bo_flink(buf->bo, &buf->flink))
149
return false;
150
buf->flinked = true;
151
}
152
153
whandle->handle = buf->flink;
154
} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
155
whandle->handle = buf->bo->handle;
156
} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
157
int fd;
158
159
if (drm_intel_bo_gem_export_to_prime(buf->bo, &fd))
160
return false;
161
whandle->handle = fd;
162
} else {
163
assert(!"unknown usage");
164
return false;
165
}
166
167
whandle->stride = stride;
168
return true;
169
}
170
171
static void *
172
i915_drm_buffer_map(struct i915_winsys *iws,
173
struct i915_winsys_buffer *buffer,
174
bool write)
175
{
176
struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
177
drm_intel_bo *bo = intel_bo(buffer);
178
int ret = 0;
179
180
assert(bo);
181
182
if (buf->map_count)
183
goto out;
184
185
ret = drm_intel_gem_bo_map_gtt(bo);
186
187
buf->ptr = bo->virtual;
188
189
assert(ret == 0);
190
out:
191
if (ret)
192
return NULL;
193
194
buf->map_count++;
195
return buf->ptr;
196
}
197
198
static void
199
i915_drm_buffer_unmap(struct i915_winsys *iws,
200
struct i915_winsys_buffer *buffer)
201
{
202
struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
203
204
if (--buf->map_count)
205
return;
206
207
drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
208
}
209
210
static int
211
i915_drm_buffer_write(struct i915_winsys *iws,
212
struct i915_winsys_buffer *buffer,
213
size_t offset,
214
size_t size,
215
const void *data)
216
{
217
struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
218
219
return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
220
}
221
222
static void
223
i915_drm_buffer_destroy(struct i915_winsys *iws,
224
struct i915_winsys_buffer *buffer)
225
{
226
drm_intel_bo_unreference(intel_bo(buffer));
227
228
#ifdef DEBUG
229
i915_drm_buffer(buffer)->magic = 0;
230
i915_drm_buffer(buffer)->bo = NULL;
231
#endif
232
233
FREE(buffer);
234
}
235
236
static bool
237
i915_drm_buffer_is_busy(struct i915_winsys *iws,
238
struct i915_winsys_buffer *buffer)
239
{
240
struct i915_drm_buffer* i915_buffer = i915_drm_buffer(buffer);
241
if (!i915_buffer)
242
return false;
243
return drm_intel_bo_busy(i915_buffer->bo);
244
}
245
246
247
void
248
i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
249
{
250
idws->base.buffer_create = i915_drm_buffer_create;
251
idws->base.buffer_create_tiled = i915_drm_buffer_create_tiled;
252
idws->base.buffer_from_handle = i915_drm_buffer_from_handle;
253
idws->base.buffer_get_handle = i915_drm_buffer_get_handle;
254
idws->base.buffer_map = i915_drm_buffer_map;
255
idws->base.buffer_unmap = i915_drm_buffer_unmap;
256
idws->base.buffer_write = i915_drm_buffer_write;
257
idws->base.buffer_destroy = i915_drm_buffer_destroy;
258
idws->base.buffer_is_busy = i915_drm_buffer_is_busy;
259
}
260
261