Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c
4561 views
1
/**************************************************************************
2
*
3
* Copyright 2012 Francisco Jerez
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
**************************************************************************/
27
28
#ifdef HAVE_PIPE_LOADER_KMS
29
#include <fcntl.h>
30
#endif
31
32
#include "pipe_loader_priv.h"
33
34
#include "util/os_file.h"
35
#include "util/u_memory.h"
36
#include "util/u_dl.h"
37
#include "sw/dri/dri_sw_winsys.h"
38
#include "sw/kms-dri/kms_dri_sw_winsys.h"
39
#include "sw/null/null_sw_winsys.h"
40
#include "sw/wrapper/wrapper_sw_winsys.h"
41
#include "target-helpers/sw_helper_public.h"
42
#include "target-helpers/inline_debug_helper.h"
43
#include "frontend/drisw_api.h"
44
#include "frontend/sw_driver.h"
45
#include "frontend/sw_winsys.h"
46
47
48
struct pipe_loader_sw_device {
49
struct pipe_loader_device base;
50
const struct sw_driver_descriptor *dd;
51
#ifndef GALLIUM_STATIC_TARGETS
52
struct util_dl_library *lib;
53
#endif
54
struct sw_winsys *ws;
55
int fd;
56
};
57
58
#define pipe_loader_sw_device(dev) ((struct pipe_loader_sw_device *)dev)
59
60
static const struct pipe_loader_ops pipe_loader_sw_ops;
61
62
#ifdef GALLIUM_STATIC_TARGETS
63
static const struct sw_driver_descriptor driver_descriptors = {
64
.create_screen = sw_screen_create_vk,
65
.winsys = {
66
#ifdef HAVE_PIPE_LOADER_DRI
67
{
68
.name = "dri",
69
.create_winsys = dri_create_sw_winsys,
70
},
71
#endif
72
#ifdef HAVE_PIPE_LOADER_KMS
73
{
74
.name = "kms_dri",
75
.create_winsys = kms_dri_create_winsys,
76
},
77
#endif
78
#ifndef __ANDROID__
79
{
80
.name = "null",
81
.create_winsys = null_sw_create,
82
},
83
{
84
.name = "wrapped",
85
.create_winsys = wrapper_sw_winsys_wrap_pipe_screen,
86
},
87
#endif
88
{ 0 },
89
}
90
};
91
#endif
92
93
static bool
94
pipe_loader_sw_probe_init_common(struct pipe_loader_sw_device *sdev)
95
{
96
sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE;
97
sdev->base.driver_name = "swrast";
98
sdev->base.ops = &pipe_loader_sw_ops;
99
sdev->fd = -1;
100
101
#ifdef GALLIUM_STATIC_TARGETS
102
sdev->dd = &driver_descriptors;
103
if (!sdev->dd)
104
return false;
105
#else
106
const char *search_dir = getenv("GALLIUM_PIPE_SEARCH_DIR");
107
if (search_dir == NULL)
108
search_dir = PIPE_SEARCH_DIR;
109
110
sdev->lib = pipe_loader_find_module("swrast", search_dir);
111
if (!sdev->lib)
112
return false;
113
114
sdev->dd = (const struct sw_driver_descriptor *)
115
util_dl_get_proc_address(sdev->lib, "swrast_driver_descriptor");
116
117
if (!sdev->dd){
118
util_dl_close(sdev->lib);
119
sdev->lib = NULL;
120
return false;
121
}
122
#endif
123
124
return true;
125
}
126
127
static void
128
pipe_loader_sw_probe_teardown_common(struct pipe_loader_sw_device *sdev)
129
{
130
#ifndef GALLIUM_STATIC_TARGETS
131
if (sdev->lib)
132
util_dl_close(sdev->lib);
133
#endif
134
}
135
136
#ifdef HAVE_PIPE_LOADER_DRI
137
bool
138
pipe_loader_sw_probe_dri(struct pipe_loader_device **devs, const struct drisw_loader_funcs *drisw_lf)
139
{
140
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
141
int i;
142
143
if (!sdev)
144
return false;
145
146
if (!pipe_loader_sw_probe_init_common(sdev))
147
goto fail;
148
149
for (i = 0; sdev->dd->winsys[i].name; i++) {
150
if (strcmp(sdev->dd->winsys[i].name, "dri") == 0) {
151
sdev->ws = sdev->dd->winsys[i].create_winsys(drisw_lf);
152
break;
153
}
154
}
155
if (!sdev->ws)
156
goto fail;
157
158
*devs = &sdev->base;
159
return true;
160
161
fail:
162
pipe_loader_sw_probe_teardown_common(sdev);
163
FREE(sdev);
164
return false;
165
}
166
#endif
167
168
#ifdef HAVE_PIPE_LOADER_KMS
169
bool
170
pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd)
171
{
172
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
173
int i;
174
175
if (!sdev)
176
return false;
177
178
if (!pipe_loader_sw_probe_init_common(sdev))
179
goto fail;
180
181
if (fd < 0 || (sdev->fd = os_dupfd_cloexec(fd)) < 0)
182
goto fail;
183
184
for (i = 0; sdev->dd->winsys[i].name; i++) {
185
if (strcmp(sdev->dd->winsys[i].name, "kms_dri") == 0) {
186
sdev->ws = sdev->dd->winsys[i].create_winsys(sdev->fd);
187
break;
188
}
189
}
190
if (!sdev->ws)
191
goto fail;
192
193
*devs = &sdev->base;
194
return true;
195
196
fail:
197
pipe_loader_sw_probe_teardown_common(sdev);
198
if (sdev->fd != -1)
199
close(sdev->fd);
200
FREE(sdev);
201
return false;
202
}
203
#endif
204
205
bool
206
pipe_loader_sw_probe_null(struct pipe_loader_device **devs)
207
{
208
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
209
int i;
210
211
if (!sdev)
212
return false;
213
214
if (!pipe_loader_sw_probe_init_common(sdev))
215
goto fail;
216
217
for (i = 0; sdev->dd->winsys[i].name; i++) {
218
if (strcmp(sdev->dd->winsys[i].name, "null") == 0) {
219
sdev->ws = sdev->dd->winsys[i].create_winsys();
220
break;
221
}
222
}
223
if (!sdev->ws)
224
goto fail;
225
226
*devs = &sdev->base;
227
return true;
228
229
fail:
230
pipe_loader_sw_probe_teardown_common(sdev);
231
FREE(sdev);
232
return false;
233
}
234
235
int
236
pipe_loader_sw_probe(struct pipe_loader_device **devs, int ndev)
237
{
238
int i = 1;
239
240
if (i <= ndev) {
241
if (!pipe_loader_sw_probe_null(devs)) {
242
i--;
243
}
244
}
245
246
return i;
247
}
248
249
boolean
250
pipe_loader_sw_probe_wrapped(struct pipe_loader_device **dev,
251
struct pipe_screen *screen)
252
{
253
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
254
int i;
255
256
if (!sdev)
257
return false;
258
259
if (!pipe_loader_sw_probe_init_common(sdev))
260
goto fail;
261
262
for (i = 0; sdev->dd->winsys[i].name; i++) {
263
if (strcmp(sdev->dd->winsys[i].name, "wrapped") == 0) {
264
sdev->ws = sdev->dd->winsys[i].create_winsys(screen);
265
break;
266
}
267
}
268
if (!sdev->ws)
269
goto fail;
270
271
*dev = &sdev->base;
272
return true;
273
274
fail:
275
pipe_loader_sw_probe_teardown_common(sdev);
276
FREE(sdev);
277
return false;
278
}
279
280
static void
281
pipe_loader_sw_release(struct pipe_loader_device **dev)
282
{
283
UNUSED struct pipe_loader_sw_device *sdev =
284
pipe_loader_sw_device(*dev);
285
286
#ifndef GALLIUM_STATIC_TARGETS
287
if (sdev->lib)
288
util_dl_close(sdev->lib);
289
#endif
290
291
#ifdef HAVE_PIPE_LOADER_KMS
292
if (sdev->fd != -1)
293
close(sdev->fd);
294
#endif
295
296
pipe_loader_base_release(dev);
297
}
298
299
static const struct driOptionDescription *
300
pipe_loader_sw_get_driconf(struct pipe_loader_device *dev, unsigned *count)
301
{
302
*count = 0;
303
return NULL;
304
}
305
306
static struct pipe_screen *
307
pipe_loader_sw_create_screen(struct pipe_loader_device *dev,
308
const struct pipe_screen_config *config, bool sw_vk)
309
{
310
struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(dev);
311
struct pipe_screen *screen;
312
313
screen = sdev->dd->create_screen(sdev->ws, sw_vk);
314
if (!screen)
315
sdev->ws->destroy(sdev->ws);
316
317
return screen ? debug_screen_wrap(screen) : NULL;
318
}
319
320
static const struct pipe_loader_ops pipe_loader_sw_ops = {
321
.create_screen = pipe_loader_sw_create_screen,
322
.get_driconf = pipe_loader_sw_get_driconf,
323
.release = pipe_loader_sw_release
324
};
325
326