• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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