1 /*
2 * Copyright 2024 Red Hat, Inc.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 /*
8 * Compatibility stub for Xorg. This responds to just enough of the legacy DRI
9 * interface to allow the X server to initialize GLX and enable direct
10 * rendering clients. It implements the screen creation hook and provides a
11 * (static, unambitious) list of framebuffer configs. It will not create an
12 * indirect context; Indirect contexts have been disabled by default since
13 * 2014 and would be limited to GL 1.4 in any case, so this is no great loss.
14 *
15 * If you do want indirect contexts to work, you have options. This stub is
16 * new with Mesa 24.1, so one option is to use an older Mesa release stream.
17 * Another option is to use an X server that does not need this interface. For
18 * Xwayland and Xephyr that's XX.X or newer, and for Xorg drivers using glamor
19 * for acceleration that's YY.Y or newer.
20 */
21
22 #include "main/glconfig.h"
23 #include "main/mtypes.h"
24 #include <GL/internal/dri_interface.h>
25 #include <dlfcn.h>
26 #include <EGL/egl.h>
27 #include <EGL/eglext.h>
28 #include "gbm/main/gbm.h"
29 #include "drm-uapi/drm_fourcc.h"
30
31 #define EGL_PLATFORM_GBM_MESA 0x31D7
32
33 /* avoid needing X11 headers */
34 #define GLX_NONE 0x8000
35 #define GLX_DONT_CARE 0xFFFFFFFF
36
37 #define CONFIG_ZS(color, zs) \
38 { \
39 .color_format = color, \
40 .zs_format = zs, \
41 }
42
43 #define CONFIG(color) \
44 CONFIG_ZS(color, PIPE_FORMAT_S8_UINT), \
45 CONFIG_ZS(color, PIPE_FORMAT_Z24_UNORM_S8_UINT), \
46 CONFIG_ZS(color, PIPE_FORMAT_Z24X8_UNORM), \
47 CONFIG_ZS(color, PIPE_FORMAT_Z16_UNORM), \
48 CONFIG_ZS(color, PIPE_FORMAT_NONE) \
49
50 /*
51 * (copy of a comment in dri_screen.c:dri_fill_in_modes())
52 *
53 * The 32-bit RGBA format must not precede the 32-bit BGRA format.
54 * Likewise for RGBX and BGRX. Otherwise, the GLX client and the GLX
55 * server may disagree on which format the GLXFBConfig represents,
56 * resulting in swapped color channels.
57 *
58 * The problem, as of 2017-05-30:
59 * When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel
60 * order and chooses the first __DRIconfig with the expected channel
61 * sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's
62 * __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK.
63 *
64 * EGL does not suffer from this problem. It correctly compares the
65 * channel masks when matching EGLConfig to __DRIconfig.
66 */
67
68 static const struct gl_config drilConfigs[] = {
69 CONFIG(PIPE_FORMAT_B8G8R8A8_UNORM),
70 CONFIG(PIPE_FORMAT_B8G8R8X8_UNORM),
71 CONFIG(PIPE_FORMAT_R8G8B8A8_UNORM),
72 CONFIG(PIPE_FORMAT_R8G8B8X8_UNORM),
73 CONFIG(PIPE_FORMAT_B10G10R10A2_UNORM),
74 CONFIG(PIPE_FORMAT_B10G10R10X2_UNORM),
75 CONFIG(PIPE_FORMAT_R10G10B10A2_UNORM),
76 CONFIG(PIPE_FORMAT_R10G10B10X2_UNORM),
77 CONFIG(PIPE_FORMAT_B5G6R5_UNORM),
78 CONFIG(PIPE_FORMAT_B5G5R5A1_UNORM),
79 CONFIG(PIPE_FORMAT_B5G5R5X1_UNORM),
80 CONFIG(PIPE_FORMAT_B4G4R4A4_UNORM),
81 CONFIG(PIPE_FORMAT_B4G4R4X4_UNORM),
82 CONFIG(PIPE_FORMAT_R5G6B5_UNORM),
83 CONFIG(PIPE_FORMAT_R5G5B5A1_UNORM),
84 CONFIG(PIPE_FORMAT_R5G5B5X1_UNORM),
85 CONFIG(PIPE_FORMAT_R4G4B4A4_UNORM),
86 CONFIG(PIPE_FORMAT_R4G4B4X4_UNORM),
87 };
88
89 #define RGB UTIL_FORMAT_COLORSPACE_RGB
90 #define RED 0
91 #define GREEN 1
92 #define BLUE 2
93 #define ALPHA 3
94 #define ZS UTIL_FORMAT_COLORSPACE_ZS
95 #define DEPTH 0
96 #define STENCIL 1
97
98 #define CASE(ATTRIB, VALUE) \
99 case __DRI_ATTRIB_ ## ATTRIB : \
100 *value = VALUE; \
101 break;
102
103 #define SIZE(f, cs, chan) (f ? util_format_get_component_bits(f, cs, chan) : 0)
104 #define SHIFT(f, cs, chan) (f ? util_format_get_component_shift(f, cs, chan) : 0)
105 #define MASK(f, cs, chan) \
106 (((1 << SIZE(f, cs, chan)) - 1) << SHIFT(f, cs, chan))
107
108 static int
drilIndexConfigAttrib(const __DRIconfig * _config,int index,unsigned int * attrib,unsigned int * value)109 drilIndexConfigAttrib(const __DRIconfig *_config, int index,
110 unsigned int *attrib, unsigned int *value)
111 {
112 struct gl_config *config = (void *)_config;
113 enum pipe_format color_format = config->color_format;
114 enum pipe_format zs_format = config->zs_format;
115 enum pipe_format accum_format = config->accum_format;
116
117 if (index >= __DRI_ATTRIB_MAX)
118 return 0;
119
120 switch (index) {
121 case __DRI_ATTRIB_SAMPLE_BUFFERS:
122 *value = !!config->samples;
123 break;
124
125 case __DRI_ATTRIB_BUFFER_SIZE: {
126 unsigned int red = 0, green = 0, blue = 0, alpha = 0;
127 drilIndexConfigAttrib(_config, __DRI_ATTRIB_RED_SIZE, attrib, &red);
128 drilIndexConfigAttrib(_config, __DRI_ATTRIB_GREEN_SIZE, attrib, &green);
129 drilIndexConfigAttrib(_config, __DRI_ATTRIB_BLUE_SIZE, attrib, &blue);
130 drilIndexConfigAttrib(_config, __DRI_ATTRIB_ALPHA_SIZE, attrib, &alpha);
131 *value = red + green + blue + alpha;
132 break;
133 }
134
135 CASE(RED_SIZE, SIZE(color_format, RGB, 0));
136 CASE(GREEN_SIZE, SIZE(color_format, RGB, 1));
137 CASE(BLUE_SIZE, SIZE(color_format, RGB, 2));
138 CASE(ALPHA_SIZE, SIZE(color_format, RGB, 3));
139 CASE(DEPTH_SIZE, SIZE(zs_format, ZS, 0));
140 CASE(STENCIL_SIZE, SIZE(zs_format, ZS, 1));
141 CASE(ACCUM_RED_SIZE, SIZE(accum_format, RGB, 0));
142 CASE(ACCUM_GREEN_SIZE, SIZE(accum_format, RGB, 1));
143 CASE(ACCUM_BLUE_SIZE, SIZE(accum_format, RGB, 2));
144 CASE(ACCUM_ALPHA_SIZE, SIZE(accum_format, RGB, 3));
145
146 CASE(RENDER_TYPE, __DRI_ATTRIB_RGBA_BIT);
147 CASE(CONFORMANT, GL_TRUE);
148 CASE(DOUBLE_BUFFER, config->doubleBufferMode);
149 CASE(SAMPLES, config->samples);
150 CASE(FRAMEBUFFER_SRGB_CAPABLE, config->sRGBCapable);
151
152 CASE(TRANSPARENT_TYPE, GLX_NONE);
153 CASE(TRANSPARENT_INDEX_VALUE, GLX_NONE);
154 CASE(TRANSPARENT_RED_VALUE, GLX_DONT_CARE);
155 CASE(TRANSPARENT_GREEN_VALUE, GLX_DONT_CARE);
156 CASE(TRANSPARENT_BLUE_VALUE, GLX_DONT_CARE);
157 CASE(TRANSPARENT_ALPHA_VALUE, GLX_DONT_CARE);
158
159 CASE(RED_MASK, MASK(color_format, RGB, 0));
160 CASE(GREEN_MASK, MASK(color_format, RGB, 1));
161 CASE(BLUE_MASK, MASK(color_format, RGB, 2));
162 CASE(ALPHA_MASK, MASK(color_format, RGB, 3));
163
164 CASE(SWAP_METHOD, __DRI_ATTRIB_SWAP_UNDEFINED);
165 CASE(MAX_SWAP_INTERVAL, INT_MAX);
166 CASE(BIND_TO_TEXTURE_RGB, GL_TRUE);
167 CASE(BIND_TO_TEXTURE_RGBA, GL_TRUE);
168 CASE(BIND_TO_TEXTURE_TARGETS,
169 __DRI_ATTRIB_TEXTURE_1D_BIT |
170 __DRI_ATTRIB_TEXTURE_2D_BIT |
171 __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT);
172 CASE(YINVERTED, GL_TRUE);
173
174 CASE(RED_SHIFT, SHIFT(color_format, RGB, 0));
175 CASE(GREEN_SHIFT, SHIFT(color_format, RGB, 1));
176 CASE(BLUE_SHIFT, SHIFT(color_format, RGB, 2));
177 CASE(ALPHA_SHIFT, SHIFT(color_format, RGB, 3));
178
179 default:
180 *value = 0;
181 break;
182 }
183
184 *attrib = index;
185 return 1;
186 }
187
188 static void
drilDestroyScreen(__DRIscreen * screen)189 drilDestroyScreen(__DRIscreen *screen)
190 {
191 /* At the moment this is just the bounce table for the configs */
192 free(screen);
193 }
194
195 static const __DRI2flushControlExtension dri2FlushControlExtension = {
196 .base = { __DRI2_FLUSH_CONTROL, 1 }
197 };
198
199 static void
dril_set_tex_buffer2(__DRIcontext * pDRICtx,GLint target,GLint format,__DRIdrawable * dPriv)200 dril_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
201 GLint format, __DRIdrawable *dPriv)
202 {
203 }
204
205 static void
dril_set_tex_buffer(__DRIcontext * pDRICtx,GLint target,__DRIdrawable * dPriv)206 dril_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
207 __DRIdrawable *dPriv)
208 {
209 }
210
211 const __DRItexBufferExtension driTexBufferExtension = {
212 .base = { __DRI_TEX_BUFFER, 2 },
213
214 .setTexBuffer = dril_set_tex_buffer,
215 .setTexBuffer2 = dril_set_tex_buffer2,
216 .releaseTexBuffer = NULL,
217 };
218
219 static const __DRIrobustnessExtension dri2Robustness = {
220 .base = { __DRI2_ROBUSTNESS, 1 }
221 };
222
223 static const __DRIextension *dril_extensions[] = {
224 &dri2FlushControlExtension.base,
225 &driTexBufferExtension.base,
226 &dri2Robustness.base,
227 NULL
228 };
229
230 /* This has to return a pointer to NULL, not just NULL */
231 static const __DRIextension **
drilGetExtensions(__DRIscreen * screen)232 drilGetExtensions(__DRIscreen *screen)
233 {
234 return (void*)&dril_extensions;
235 }
236
237 static __DRIcontext *
drilCreateContextAttribs(__DRIscreen * psp,int api,const __DRIconfig * config,__DRIcontext * shared,unsigned num_attribs,const uint32_t * attribs,unsigned * error,void * data)238 drilCreateContextAttribs(__DRIscreen *psp, int api,
239 const __DRIconfig *config,
240 __DRIcontext *shared,
241 unsigned num_attribs,
242 const uint32_t *attribs,
243 unsigned *error,
244 void *data)
245 {
246 return NULL;
247 }
248
249 static __DRIcontext *
drilCreateNewContextForAPI(__DRIscreen * screen,int api,const __DRIconfig * config,__DRIcontext * shared,void * data)250 drilCreateNewContextForAPI(__DRIscreen *screen, int api,
251 const __DRIconfig *config,
252 __DRIcontext *shared, void *data)
253 {
254 return NULL;
255 }
256
257 static __DRIcontext *
drilCreateNewContext(__DRIscreen * screen,const __DRIconfig * config,__DRIcontext * shared,void * data)258 drilCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
259 __DRIcontext *shared, void *data)
260 {
261 return NULL;
262 }
263
264 static void
drilDestroyDrawable(__DRIdrawable * pdp)265 drilDestroyDrawable(__DRIdrawable *pdp)
266 {
267 }
268
269 static const __DRIcoreExtension drilCoreExtension = {
270 .base = { __DRI_CORE, 1 },
271
272 .destroyScreen = drilDestroyScreen,
273 .getExtensions = drilGetExtensions,
274 .getConfigAttrib = NULL, // XXX not actually used!
275 .indexConfigAttrib = drilIndexConfigAttrib,
276 .destroyDrawable = drilDestroyDrawable,
277 .createNewContext = drilCreateNewContext,
278 };
279
drilBindContext(__DRIcontext * pcp,__DRIdrawable * pdp,__DRIdrawable * prp)280 static int drilBindContext(__DRIcontext *pcp,
281 __DRIdrawable *pdp,
282 __DRIdrawable *prp)
283 {
284 return 0; // Success
285 }
286
drilUnbindContext(__DRIcontext * pcp)287 static int drilUnbindContext(__DRIcontext *pcp)
288 {
289 return 0; // Success
290 }
291
292 static __DRIdrawable *
drilCreateNewDrawable(__DRIscreen * psp,const __DRIconfig * config,void * data)293 drilCreateNewDrawable(__DRIscreen *psp,
294 const __DRIconfig *config,
295 void *data)
296 {
297 return NULL;
298 }
299
300
301 static enum pipe_format
fourcc_to_pipe_format(int fourcc)302 fourcc_to_pipe_format(int fourcc)
303 {
304 switch (fourcc) {
305 case DRM_FORMAT_RGB565: return PIPE_FORMAT_B5G6R5_UNORM;
306 case DRM_FORMAT_XRGB8888: return PIPE_FORMAT_BGRX8888_UNORM;
307 case DRM_FORMAT_ARGB8888: return PIPE_FORMAT_BGRA8888_UNORM;
308 case DRM_FORMAT_ABGR8888: return PIPE_FORMAT_RGBA8888_UNORM;
309 case DRM_FORMAT_XBGR8888: return PIPE_FORMAT_RGBX8888_UNORM;
310 case DRM_FORMAT_XRGB2101010: return PIPE_FORMAT_B10G10R10X2_UNORM;
311 case DRM_FORMAT_ARGB2101010: return PIPE_FORMAT_B10G10R10A2_UNORM;
312 case DRM_FORMAT_XBGR2101010: return PIPE_FORMAT_R10G10B10X2_UNORM;
313 case DRM_FORMAT_ABGR2101010: return PIPE_FORMAT_R10G10B10A2_UNORM;
314 case DRM_FORMAT_XBGR16161616F: return PIPE_FORMAT_R16G16B16A16_FLOAT;
315 case DRM_FORMAT_ABGR16161616F: return PIPE_FORMAT_R16G16B16X16_FLOAT;
316 case DRM_FORMAT_ARGB1555: return PIPE_FORMAT_B5G5R5A1_UNORM;
317 case DRM_FORMAT_ABGR1555: return PIPE_FORMAT_R5G5B5A1_UNORM;
318 case DRM_FORMAT_ARGB4444: return PIPE_FORMAT_B4G4R4A4_UNORM;
319 case DRM_FORMAT_ABGR4444: return PIPE_FORMAT_R4G4B4A4_UNORM;
320 default: return PIPE_FORMAT_NONE;
321 }
322 }
323
324 static unsigned
add_srgb_config(struct gl_config ** configs,unsigned c,enum pipe_format last_pformat,unsigned last_start)325 add_srgb_config(struct gl_config **configs, unsigned c, enum pipe_format last_pformat, unsigned last_start)
326 {
327 enum pipe_format srgb = util_format_srgb(last_pformat);
328 if (!srgb)
329 return c;
330 unsigned end = c;
331 for (unsigned j = last_start; j < end; j++) {
332 configs[c] = mem_dup(configs[j], sizeof(drilConfigs[j]));
333
334 struct gl_config *cfg = configs[c++];
335 cfg->color_format = srgb;
336 cfg->sRGBCapable = 1;
337 }
338 return c;
339 }
340
341 /* DRI2 awfulness */
342 static const __DRIconfig **
init_dri2_configs(int fd)343 init_dri2_configs(int fd)
344 {
345 void *egl = NULL;
346 struct gl_config **configs = NULL;
347 unsigned c = 0;
348 enum pipe_format last_pformat = 0;
349 unsigned last_start = 0;
350
351 /* dlopen/dlsym to avoid linkage */
352 egl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL);
353 if (!egl)
354 return false;
355
356 void * (*peglGetProcAddress)(const char *) = dlsym(egl, "eglGetProcAddress");
357 EGLDisplay (*peglGetPlatformDisplayEXT)(EGLenum, void *, const EGLint *) = peglGetProcAddress("eglGetPlatformDisplayEXT");
358 EGLBoolean (*peglInitialize)(EGLDisplay, int*, int*) = peglGetProcAddress("eglInitialize");
359 EGLBoolean (*peglTerminate)(EGLDisplay) = peglGetProcAddress("eglTerminate");
360 EGLBoolean (*peglGetConfigs)(EGLDisplay, EGLConfig*, EGLint, EGLint*) = peglGetProcAddress("eglGetConfigs");
361 EGLBoolean (*peglGetConfigAttrib)(EGLDisplay, EGLConfig, EGLint, EGLint *) = peglGetProcAddress("eglGetConfigAttrib");
362 const char *(*peglQueryString)(EGLDisplay, EGLint) = peglGetProcAddress("eglQueryString");
363
364 struct gbm_device *gbm = NULL;
365 if (fd != -1) {
366 /* try opening GBM for hardware driver info */
367 gbm = gbm_create_device(fd);
368 if (!gbm)
369 goto out;
370 }
371
372 EGLDisplay dpy = peglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, gbm ? gbm : EGL_DEFAULT_DISPLAY, NULL);
373 if (!dpy)
374 goto out_gbm;
375 int maj, min;
376 if (!peglInitialize(dpy, &maj, &min))
377 goto out_gbm;
378
379 const char *egl_extension_list = peglQueryString(dpy, EGL_EXTENSIONS);
380 bool has_srgb = strstr(egl_extension_list, "EGL_KHR_gl_colorspace");
381
382 int num_configs = 0;
383 EGLConfig *eglconfigs = NULL;
384 if (!peglGetConfigs(dpy, NULL, 0, &num_configs))
385 goto out_egl;
386 eglconfigs = malloc(sizeof(EGLConfig) * num_configs);
387 /* overestimate: num_configs * doubleBuffer * sRGB + NULL */
388 configs = calloc(num_configs * 2 * 2 + 1, sizeof(struct gl_config));
389 if (!peglGetConfigs(dpy, eglconfigs, num_configs, &num_configs))
390 goto out_egl;
391
392 for (unsigned i = 0; i < num_configs; i++) {
393 /* verify that this is the right format */
394 EGLint format, depth, stencil, samples;
395
396 if (!peglGetConfigAttrib(dpy, eglconfigs[i], EGL_NATIVE_VISUAL_ID, &format) ||
397 !peglGetConfigAttrib(dpy, eglconfigs[i], EGL_DEPTH_SIZE, &depth) ||
398 !peglGetConfigAttrib(dpy, eglconfigs[i], EGL_STENCIL_SIZE, &stencil) ||
399 !peglGetConfigAttrib(dpy, eglconfigs[i], EGL_SAMPLES, &samples))
400 continue;
401
402 enum pipe_format pformat = fourcc_to_pipe_format(format);
403
404 /* srgb configs go after base configs */
405 if (last_pformat && has_srgb && pformat != last_pformat)
406 c = add_srgb_config(configs, c, last_pformat, last_start);
407 /* tracking for the number of srgb configs to create */
408 if (pformat != last_pformat)
409 last_start = c;
410
411 for (unsigned j = 0; j < ARRAY_SIZE(drilConfigs); j++) {
412 unsigned depth_size = SIZE(drilConfigs[j].zs_format, ZS, 0);
413 unsigned stencil_size = SIZE(drilConfigs[j].zs_format, ZS, 1);
414 /* only copy supported configs */
415 if (pformat != drilConfigs[j].color_format || depth != depth_size || stencil != stencil_size)
416 continue;
417
418 /* always create single-buffered and double-buffered */
419 for (unsigned k = 0; k < 2; k++) {
420 configs[c] = mem_dup(&drilConfigs[j], sizeof(drilConfigs[j]));
421
422 struct gl_config *cfg = configs[c++];
423 cfg->samples = samples;
424 cfg->doubleBufferMode = k;
425 }
426 break;
427 }
428 last_pformat = pformat;
429 }
430 /* check last format for srgbness too */
431 if (c && has_srgb)
432 c = add_srgb_config(configs, c, last_pformat, last_start);
433 out_egl:
434 free(eglconfigs);
435 /* don't forget cleanup */
436 peglTerminate(dpy);
437
438 out_gbm:
439 if (gbm)
440 gbm_device_destroy(gbm);
441 out:
442 dlclose(egl);
443 if (c)
444 return (void*)configs;
445 free(configs);
446 return NULL;
447 }
448
449 static __DRIscreen *
drilCreateNewScreen(int scrn,int fd,const __DRIextension ** loader_extensions,const __DRIextension ** driver_extensions,const __DRIconfig *** driver_configs,void * data)450 drilCreateNewScreen(int scrn, int fd,
451 const __DRIextension **loader_extensions,
452 const __DRIextension **driver_extensions,
453 const __DRIconfig ***driver_configs, void *data)
454 {
455 const __DRIconfig **configs = init_dri2_configs(fd);
456 if (!configs && fd == -1) {
457 // otherwise set configs to point to our config list
458 configs = calloc(ARRAY_SIZE(drilConfigs) * 2 + 1, sizeof(void *));
459 int c = 0;
460 for (int i = 0; i < ARRAY_SIZE(drilConfigs); i++) {
461 /* create normal config */
462 configs[c++] = mem_dup(&drilConfigs[i], sizeof(drilConfigs[i]));
463
464 /* create double-buffered config */
465 configs[c] = mem_dup(&drilConfigs[i], sizeof(drilConfigs[i]));
466 struct gl_config *cfg = (void*)configs[c++];
467 cfg->doubleBufferMode = 1;
468 }
469 }
470
471 // outpointer it
472 *driver_configs = configs;
473
474 // This has to be a separate allocation from the configs.
475 // If we had any additional screen state we'd need to do
476 // something less hacky.
477 return malloc(sizeof(int));
478 }
479
480 const __DRIextension *__driDriverExtensions[];
481
482 static __DRIscreen *
dril2CreateNewScreen(int scrn,int fd,const __DRIextension ** extensions,const __DRIconfig *** driver_configs,void * data)483 dril2CreateNewScreen(int scrn, int fd,
484 const __DRIextension **extensions,
485 const __DRIconfig ***driver_configs, void *data)
486 {
487 return drilCreateNewScreen(scrn, fd,
488 extensions,
489 __driDriverExtensions,
490 driver_configs, data);
491 }
492
493 static __DRIscreen *
drilSWCreateNewScreen(int scrn,const __DRIextension ** extensions,const __DRIconfig *** driver_configs,void * data)494 drilSWCreateNewScreen(int scrn, const __DRIextension **extensions,
495 const __DRIconfig ***driver_configs,
496 void *data)
497 {
498 return drilCreateNewScreen(scrn, -1,
499 extensions,
500 __driDriverExtensions,
501 driver_configs, data);
502 }
503
504 static __DRIscreen *
drilSWCreateNewScreen2(int scrn,const __DRIextension ** extensions,const __DRIextension ** driver_extensions,const __DRIconfig *** driver_configs,void * data)505 drilSWCreateNewScreen2(int scrn, const __DRIextension **extensions,
506 const __DRIextension **driver_extensions,
507 const __DRIconfig ***driver_configs, void *data)
508 {
509 return drilCreateNewScreen(scrn, -1,
510 extensions,
511 __driDriverExtensions,
512 driver_configs, data);
513 }
514
515 static int
drilSWQueryBufferAge(__DRIdrawable * pdp)516 drilSWQueryBufferAge(__DRIdrawable *pdp)
517 {
518 return 0;
519 }
520
521
522 static const __DRIswrastExtension drilSWRastExtension = {
523 .base = { __DRI_SWRAST, 5 },
524
525 .createNewScreen = drilSWCreateNewScreen,
526 .createNewDrawable = drilCreateNewDrawable,
527 .createNewContextForAPI = drilCreateNewContextForAPI,
528 .createContextAttribs = drilCreateContextAttribs,
529 .createNewScreen2 = drilSWCreateNewScreen2,
530 .queryBufferAge = drilSWQueryBufferAge,
531 };
532
533 const __DRIdri2Extension drilDRI2Extension = {
534 .base = { __DRI_DRI2, 5 },
535
536 /* these are the methods used by the xserver */
537 .createNewScreen = dril2CreateNewScreen,
538 .createNewDrawable = drilCreateNewDrawable,
539 .createNewContext = drilCreateNewContext,
540 .createContextAttribs = drilCreateContextAttribs,
541 };
542
543 const __DRIextension *__driDriverExtensions[] = {
544 &drilCoreExtension.base,
545 &drilSWRastExtension.base,
546 &drilDRI2Extension.base,
547 NULL
548 };
549
550 #include "util/detect_os.h"
551
552 #include "target-helpers/drm_helper.h"
553 #include "target-helpers/sw_helper.h"
554
555 #define DEFINE_LOADER_DRM_ENTRYPOINT(drivername) \
556 const __DRIextension **__driDriverGetExtensions_##drivername(void); \
557 PUBLIC const __DRIextension **__driDriverGetExtensions_##drivername(void) \
558 { \
559 return __driDriverExtensions; \
560 }
561
562 const __DRIextension **__driDriverGetExtensions_swrast(void);
563
__driDriverGetExtensions_swrast(void)564 PUBLIC const __DRIextension **__driDriverGetExtensions_swrast(void)
565 {
566 return __driDriverExtensions;
567 }
568
569 const __DRIextension **__driDriverGetExtensions_kms_swrast(void);
570
__driDriverGetExtensions_kms_swrast(void)571 PUBLIC const __DRIextension **__driDriverGetExtensions_kms_swrast(void)
572 {
573 return __driDriverExtensions;
574 }
575
576 DEFINE_LOADER_DRM_ENTRYPOINT(i915)
577 DEFINE_LOADER_DRM_ENTRYPOINT(iris)
578 DEFINE_LOADER_DRM_ENTRYPOINT(crocus)
579 DEFINE_LOADER_DRM_ENTRYPOINT(nouveau)
580 DEFINE_LOADER_DRM_ENTRYPOINT(r300)
581 DEFINE_LOADER_DRM_ENTRYPOINT(r600)
582 DEFINE_LOADER_DRM_ENTRYPOINT(radeonsi)
583 DEFINE_LOADER_DRM_ENTRYPOINT(vmwgfx)
584 DEFINE_LOADER_DRM_ENTRYPOINT(msm)
585 DEFINE_LOADER_DRM_ENTRYPOINT(kgsl)
586 DEFINE_LOADER_DRM_ENTRYPOINT(virtio_gpu)
587 DEFINE_LOADER_DRM_ENTRYPOINT(v3d)
588 DEFINE_LOADER_DRM_ENTRYPOINT(vc4)
589 DEFINE_LOADER_DRM_ENTRYPOINT(panfrost)
590 DEFINE_LOADER_DRM_ENTRYPOINT(panthor)
591 DEFINE_LOADER_DRM_ENTRYPOINT(asahi)
592 DEFINE_LOADER_DRM_ENTRYPOINT(etnaviv)
593 DEFINE_LOADER_DRM_ENTRYPOINT(tegra)
594 DEFINE_LOADER_DRM_ENTRYPOINT(armada_drm)
595 DEFINE_LOADER_DRM_ENTRYPOINT(exynos)
596 DEFINE_LOADER_DRM_ENTRYPOINT(gm12u320)
597 DEFINE_LOADER_DRM_ENTRYPOINT(hdlcd)
598 DEFINE_LOADER_DRM_ENTRYPOINT(hx8357d)
599 DEFINE_LOADER_DRM_ENTRYPOINT(ili9163)
600 DEFINE_LOADER_DRM_ENTRYPOINT(ili9225)
601 DEFINE_LOADER_DRM_ENTRYPOINT(ili9341)
602 DEFINE_LOADER_DRM_ENTRYPOINT(ili9486)
603 DEFINE_LOADER_DRM_ENTRYPOINT(imx_drm)
604 DEFINE_LOADER_DRM_ENTRYPOINT(imx_dcss)
605 DEFINE_LOADER_DRM_ENTRYPOINT(imx_lcdif)
606 DEFINE_LOADER_DRM_ENTRYPOINT(ingenic_drm)
607 DEFINE_LOADER_DRM_ENTRYPOINT(kirin)
608 DEFINE_LOADER_DRM_ENTRYPOINT(komeda)
609 DEFINE_LOADER_DRM_ENTRYPOINT(mali_dp)
610 DEFINE_LOADER_DRM_ENTRYPOINT(mcde)
611 DEFINE_LOADER_DRM_ENTRYPOINT(mediatek)
612 DEFINE_LOADER_DRM_ENTRYPOINT(meson)
613 DEFINE_LOADER_DRM_ENTRYPOINT(mi0283qt)
614 DEFINE_LOADER_DRM_ENTRYPOINT(mxsfb_drm)
615 DEFINE_LOADER_DRM_ENTRYPOINT(panel_mipi_dbi)
616 DEFINE_LOADER_DRM_ENTRYPOINT(pl111)
617 DEFINE_LOADER_DRM_ENTRYPOINT(rcar_du)
618 DEFINE_LOADER_DRM_ENTRYPOINT(repaper)
619 DEFINE_LOADER_DRM_ENTRYPOINT(rockchip)
620 DEFINE_LOADER_DRM_ENTRYPOINT(rzg2l_du)
621 DEFINE_LOADER_DRM_ENTRYPOINT(ssd130x)
622 DEFINE_LOADER_DRM_ENTRYPOINT(st7586)
623 DEFINE_LOADER_DRM_ENTRYPOINT(st7735r)
624 DEFINE_LOADER_DRM_ENTRYPOINT(sti)
625 DEFINE_LOADER_DRM_ENTRYPOINT(stm)
626 DEFINE_LOADER_DRM_ENTRYPOINT(sun4i_drm)
627 DEFINE_LOADER_DRM_ENTRYPOINT(udl)
628 DEFINE_LOADER_DRM_ENTRYPOINT(zynqmp_dpsub)
629 DEFINE_LOADER_DRM_ENTRYPOINT(lima)
630 DEFINE_LOADER_DRM_ENTRYPOINT(d3d12)
631 DEFINE_LOADER_DRM_ENTRYPOINT(zink)
632