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