• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * (C) Copyright IBM Corporation 2002, 2004
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * \file dri_util.c
27  * DRI utility functions.
28  *
29  * This module acts as glue between GLX and the actual hardware driver.  A DRI
30  * driver doesn't really \e have to use any of this - it's optional.  But, some
31  * useful stuff is done here that otherwise would have to be duplicated in most
32  * drivers.
33  *
34  * Basically, these utility functions take care of some of the dirty details of
35  * screen initialization, context creation, context binding, DRM setup, etc.
36  *
37  * These functions are compiled into each DRI driver so libGL.so knows nothing
38  * about them.
39  */
40 
41 
42 #include <stdbool.h>
43 #include "dri_util.h"
44 #include "dri_context.h"
45 #include "dri_screen.h"
46 #include "util/u_endian.h"
47 #include "util/driconf.h"
48 #include "main/framebuffer.h"
49 #include "main/version.h"
50 #include "main/debug_output.h"
51 #include "main/errors.h"
52 
53 driOptionDescription __dri2ConfigOptions[] = {
54       DRI_CONF_SECTION_DEBUG
55          DRI_CONF_GLX_EXTENSION_OVERRIDE()
56          DRI_CONF_INDIRECT_GL_EXTENSION_OVERRIDE()
57       DRI_CONF_SECTION_END
58 
59       DRI_CONF_SECTION_PERFORMANCE
60          DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
61       DRI_CONF_SECTION_END
62 };
63 
64 /*****************************************************************/
65 /** \name Screen handling functions                              */
66 /*****************************************************************/
67 /*@{*/
68 
69 static void
setupLoaderExtensions(__DRIscreen * psp,const __DRIextension ** extensions)70 setupLoaderExtensions(__DRIscreen *psp,
71 		      const __DRIextension **extensions)
72 {
73     int i;
74 
75     for (i = 0; extensions[i]; i++) {
76 	if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
77 	    psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
78 	if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
79 	    psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
80 	if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0)
81 	    psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
82         if (strcmp(extensions[i]->name, __DRI_BACKGROUND_CALLABLE) == 0)
83             psp->dri2.backgroundCallable = (__DRIbackgroundCallableExtension *) extensions[i];
84 	if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
85 	    psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
86         if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0)
87            psp->image.loader = (__DRIimageLoaderExtension *) extensions[i];
88         if (strcmp(extensions[i]->name, __DRI_MUTABLE_RENDER_BUFFER_LOADER) == 0)
89            psp->mutableRenderBuffer.loader = (__DRImutableRenderBufferLoaderExtension *) extensions[i];
90         if (strcmp(extensions[i]->name, __DRI_KOPPER_LOADER) == 0)
91             psp->kopper_loader = (__DRIkopperLoaderExtension *) extensions[i];
92     }
93 }
94 
95 /**
96  * This is the first entrypoint in the driver called by the DRI driver loader
97  * after dlopen()ing it.
98  *
99  * It's used to create global state for the driver across contexts on the same
100  * Display.
101  */
102 static __DRIscreen *
driCreateNewScreen2(int scrn,int fd,const __DRIextension ** extensions,const __DRIextension ** driver_extensions,const __DRIconfig *** driver_configs,void * data)103 driCreateNewScreen2(int scrn, int fd,
104                     const __DRIextension **extensions,
105                     const __DRIextension **driver_extensions,
106                     const __DRIconfig ***driver_configs, void *data)
107 {
108     static const __DRIextension *emptyExtensionList[] = { NULL };
109     __DRIscreen *psp;
110 
111     psp = calloc(1, sizeof(*psp));
112     if (!psp)
113 	return NULL;
114 
115     assert(driver_extensions);
116     for (int i = 0; driver_extensions[i]; i++) {
117        if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) {
118           psp->driver =
119              ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable;
120        }
121     }
122 
123     setupLoaderExtensions(psp, extensions);
124     // dri2 drivers require working invalidate
125     if (fd != -1 && !psp->dri2.useInvalidate) {
126        free(psp);
127        return NULL;
128     }
129 
130     psp->loaderPrivate = data;
131 
132     psp->extensions = emptyExtensionList;
133     psp->fd = fd;
134     psp->myNum = scrn;
135 
136     /* Option parsing before ->InitScreen(), as some options apply there. */
137     driParseOptionInfo(&psp->optionInfo,
138                        __dri2ConfigOptions, ARRAY_SIZE(__dri2ConfigOptions));
139     driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
140                         "dri2", NULL, NULL, NULL, 0, NULL, 0);
141 
142     *driver_configs = psp->driver->InitScreen(psp);
143     if (*driver_configs == NULL) {
144 	free(psp);
145 	return NULL;
146     }
147 
148     struct gl_constants consts = { 0 };
149     gl_api api;
150     unsigned version;
151 
152     api = API_OPENGLES2;
153     if (_mesa_override_gl_version_contextless(&consts, &api, &version))
154        psp->max_gl_es2_version = version;
155 
156     api = API_OPENGL_COMPAT;
157     if (_mesa_override_gl_version_contextless(&consts, &api, &version)) {
158        psp->max_gl_core_version = version;
159        if (api == API_OPENGL_COMPAT)
160           psp->max_gl_compat_version = version;
161     }
162 
163     psp->api_mask = 0;
164     if (psp->max_gl_compat_version > 0)
165        psp->api_mask |= (1 << __DRI_API_OPENGL);
166     if (psp->max_gl_core_version > 0)
167        psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
168     if (psp->max_gl_es1_version > 0)
169        psp->api_mask |= (1 << __DRI_API_GLES);
170     if (psp->max_gl_es2_version > 0)
171        psp->api_mask |= (1 << __DRI_API_GLES2);
172     if (psp->max_gl_es2_version >= 30)
173        psp->api_mask |= (1 << __DRI_API_GLES3);
174 
175     return psp;
176 }
177 
178 static __DRIscreen *
dri2CreateNewScreen(int scrn,int fd,const __DRIextension ** extensions,const __DRIconfig *** driver_configs,void * data)179 dri2CreateNewScreen(int scrn, int fd,
180 		    const __DRIextension **extensions,
181 		    const __DRIconfig ***driver_configs, void *data)
182 {
183    return driCreateNewScreen2(scrn, fd, extensions,
184                               galliumdrm_driver_extensions,
185                               driver_configs, data);
186 }
187 
188 static __DRIscreen *
swkmsCreateNewScreen(int scrn,int fd,const __DRIextension ** extensions,const __DRIconfig *** driver_configs,void * data)189 swkmsCreateNewScreen(int scrn, int fd,
190 		     const __DRIextension **extensions,
191 		     const __DRIconfig ***driver_configs, void *data)
192 {
193    return driCreateNewScreen2(scrn, fd, extensions,
194                               dri_swrast_kms_driver_extensions,
195                               driver_configs, data);
196 }
197 
198 /** swrast driver createNewScreen entrypoint. */
199 static __DRIscreen *
driSWRastCreateNewScreen(int scrn,const __DRIextension ** extensions,const __DRIconfig *** driver_configs,void * data)200 driSWRastCreateNewScreen(int scrn, const __DRIextension **extensions,
201                          const __DRIconfig ***driver_configs, void *data)
202 {
203    return driCreateNewScreen2(scrn, -1, extensions,
204                               galliumsw_driver_extensions,
205                               driver_configs, data);
206 }
207 
208 static __DRIscreen *
driSWRastCreateNewScreen2(int scrn,const __DRIextension ** extensions,const __DRIextension ** driver_extensions,const __DRIconfig *** driver_configs,void * data)209 driSWRastCreateNewScreen2(int scrn, const __DRIextension **extensions,
210                           const __DRIextension **driver_extensions,
211                           const __DRIconfig ***driver_configs, void *data)
212 {
213    return driCreateNewScreen2(scrn, -1, extensions, driver_extensions,
214                                driver_configs, data);
215 }
216 
217 /**
218  * Destroy the per-screen private information.
219  *
220  * \internal
221  * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
222  * drmClose(), and finally frees \p screenPrivate.
223  */
driDestroyScreen(__DRIscreen * psp)224 static void driDestroyScreen(__DRIscreen *psp)
225 {
226     if (psp) {
227 	/* No interaction with the X-server is possible at this point.  This
228 	 * routine is called after XCloseDisplay, so there is no protocol
229 	 * stream open to the X-server anymore.
230 	 */
231 
232 	psp->driver->DestroyScreen(psp);
233 
234 	driDestroyOptionCache(&psp->optionCache);
235 	driDestroyOptionInfo(&psp->optionInfo);
236 
237 	free(psp);
238     }
239 }
240 
driGetExtensions(__DRIscreen * psp)241 static const __DRIextension **driGetExtensions(__DRIscreen *psp)
242 {
243     return psp->extensions;
244 }
245 
246 /*@}*/
247 
248 /* WARNING: HACK: Local defines to avoid pulling glx.h.
249  */
250 #define GLX_NONE                                                0x8000
251 #define GLX_DONT_CARE                                           0xFFFFFFFF
252 
253 #define __ATTRIB(attrib, field) case attrib: *value = config->modes.field; break
254 
255 /**
256  * Return the value of a configuration attribute.  The attribute is
257  * indicated by the index.
258  */
259 static int
driGetConfigAttribIndex(const __DRIconfig * config,unsigned int index,unsigned int * value)260 driGetConfigAttribIndex(const __DRIconfig *config,
261 			unsigned int index, unsigned int *value)
262 {
263     switch (index + 1) {
264     __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE,			rgbBits);
265     __ATTRIB(__DRI_ATTRIB_RED_SIZE,			redBits);
266     __ATTRIB(__DRI_ATTRIB_GREEN_SIZE,			greenBits);
267     __ATTRIB(__DRI_ATTRIB_BLUE_SIZE,			blueBits);
268     case __DRI_ATTRIB_LEVEL:
269     case __DRI_ATTRIB_LUMINANCE_SIZE:
270     case __DRI_ATTRIB_AUX_BUFFERS:
271         *value = 0;
272         break;
273     __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE,			alphaBits);
274     case __DRI_ATTRIB_ALPHA_MASK_SIZE:
275         /* I have no idea what this value was ever meant to mean, it's
276          * never been set to anything, just say 0.
277          */
278         *value = 0;
279         break;
280     __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE,			depthBits);
281     __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE,			stencilBits);
282     __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE,		accumRedBits);
283     __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE,		accumGreenBits);
284     __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE,		accumBlueBits);
285     __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE,		accumAlphaBits);
286     case __DRI_ATTRIB_SAMPLE_BUFFERS:
287         *value = !!config->modes.samples;
288         break;
289     __ATTRIB(__DRI_ATTRIB_SAMPLES,			samples);
290     case __DRI_ATTRIB_RENDER_TYPE:
291         /* no support for color index mode */
292 	*value = __DRI_ATTRIB_RGBA_BIT;
293         if (config->modes.floatMode)
294             *value |= __DRI_ATTRIB_FLOAT_BIT;
295 	break;
296     case __DRI_ATTRIB_CONFIG_CAVEAT:
297 	if (config->modes.accumRedBits != 0)
298 	    *value = __DRI_ATTRIB_SLOW_BIT;
299 	else
300 	    *value = 0;
301 	break;
302     case __DRI_ATTRIB_CONFORMANT:
303         *value = GL_TRUE;
304         break;
305     __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER,		doubleBufferMode);
306     __ATTRIB(__DRI_ATTRIB_STEREO,			stereoMode);
307     case __DRI_ATTRIB_TRANSPARENT_TYPE:
308     case __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE: /* horrible bc hack */
309         *value = GLX_NONE;
310         break;
311     case __DRI_ATTRIB_TRANSPARENT_RED_VALUE:
312     case __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE:
313     case __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE:
314     case __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE:
315         *value = GLX_DONT_CARE;
316         break;
317     case __DRI_ATTRIB_FLOAT_MODE:
318         *value = config->modes.floatMode;
319         break;
320     __ATTRIB(__DRI_ATTRIB_RED_MASK,			redMask);
321     __ATTRIB(__DRI_ATTRIB_GREEN_MASK,			greenMask);
322     __ATTRIB(__DRI_ATTRIB_BLUE_MASK,			blueMask);
323     __ATTRIB(__DRI_ATTRIB_ALPHA_MASK,			alphaMask);
324     case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
325     case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
326     case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
327     case __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH:
328     case __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT:
329     case __DRI_ATTRIB_VISUAL_SELECT_GROUP:
330         *value = 0;
331         break;
332     __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			swapMethod);
333     case __DRI_ATTRIB_MAX_SWAP_INTERVAL:
334         *value = INT_MAX;
335         break;
336     case __DRI_ATTRIB_MIN_SWAP_INTERVAL:
337         *value = 0;
338         break;
339     case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
340     case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
341     case __DRI_ATTRIB_YINVERTED:
342         *value = GL_TRUE;
343         break;
344     case __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE:
345         *value = GL_FALSE;
346         break;
347     case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
348         *value = __DRI_ATTRIB_TEXTURE_1D_BIT |
349                  __DRI_ATTRIB_TEXTURE_2D_BIT |
350                  __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
351         break;
352     __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE,	sRGBCapable);
353     case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER:
354         *value = GL_FALSE;
355         break;
356     __ATTRIB(__DRI_ATTRIB_RED_SHIFT,			redShift);
357     __ATTRIB(__DRI_ATTRIB_GREEN_SHIFT,			greenShift);
358     __ATTRIB(__DRI_ATTRIB_BLUE_SHIFT,			blueShift);
359     __ATTRIB(__DRI_ATTRIB_ALPHA_SHIFT,			alphaShift);
360     default:
361         /* XXX log an error or smth */
362         return GL_FALSE;
363     }
364 
365     return GL_TRUE;
366 }
367 
368 /**
369  * Get the value of a configuration attribute.
370  * \param attrib  the attribute (one of the _DRI_ATTRIB_x tokens)
371  * \param value  returns the attribute's value
372  * \return 1 for success, 0 for failure
373  */
374 static int
driGetConfigAttrib(const __DRIconfig * config,unsigned int attrib,unsigned int * value)375 driGetConfigAttrib(const __DRIconfig *config,
376 		   unsigned int attrib, unsigned int *value)
377 {
378     return driGetConfigAttribIndex(config, attrib - 1, value);
379 }
380 
381 /**
382  * Get a configuration attribute name and value, given an index.
383  * \param index  which field of the __DRIconfig to query
384  * \param attrib  returns the attribute name (one of the _DRI_ATTRIB_x tokens)
385  * \param value  returns the attribute's value
386  * \return 1 for success, 0 for failure
387  */
388 static int
driIndexConfigAttrib(const __DRIconfig * config,int index,unsigned int * attrib,unsigned int * value)389 driIndexConfigAttrib(const __DRIconfig *config, int index,
390 		     unsigned int *attrib, unsigned int *value)
391 {
392     if (driGetConfigAttribIndex(config, index, value)) {
393         *attrib = index + 1;
394         return GL_TRUE;
395     }
396 
397     return GL_FALSE;
398 }
399 
400 static bool
validate_context_version(__DRIscreen * screen,int mesa_api,unsigned major_version,unsigned minor_version,unsigned * dri_ctx_error)401 validate_context_version(__DRIscreen *screen,
402                          int mesa_api,
403                          unsigned major_version,
404                          unsigned minor_version,
405                          unsigned *dri_ctx_error)
406 {
407    unsigned req_version = 10 * major_version + minor_version;
408    unsigned max_version = 0;
409 
410    switch (mesa_api) {
411    case API_OPENGL_COMPAT:
412       max_version = screen->max_gl_compat_version;
413       break;
414    case API_OPENGL_CORE:
415       max_version = screen->max_gl_core_version;
416       break;
417    case API_OPENGLES:
418       max_version = screen->max_gl_es1_version;
419       break;
420    case API_OPENGLES2:
421       max_version = screen->max_gl_es2_version;
422       break;
423    default:
424       max_version = 0;
425       break;
426    }
427 
428    if (max_version == 0) {
429       *dri_ctx_error = __DRI_CTX_ERROR_BAD_API;
430       return false;
431    } else if (req_version > max_version) {
432       *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION;
433       return false;
434    }
435 
436    return true;
437 }
438 
439 /*****************************************************************/
440 /** \name Context handling functions                             */
441 /*****************************************************************/
442 /*@{*/
443 
444 static __DRIcontext *
driCreateContextAttribs(__DRIscreen * screen,int api,const __DRIconfig * config,__DRIcontext * shared,unsigned num_attribs,const uint32_t * attribs,unsigned * error,void * data)445 driCreateContextAttribs(__DRIscreen *screen, int api,
446                         const __DRIconfig *config,
447                         __DRIcontext *shared,
448                         unsigned num_attribs,
449                         const uint32_t *attribs,
450                         unsigned *error,
451                         void *data)
452 {
453     __DRIcontext *context;
454     const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
455     void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
456     gl_api mesa_api;
457     struct __DriverContextConfig ctx_config;
458 
459     ctx_config.major_version = 1;
460     ctx_config.minor_version = 0;
461     ctx_config.flags = 0;
462     ctx_config.attribute_mask = 0;
463     ctx_config.priority = __DRI_CTX_PRIORITY_MEDIUM;
464 
465     assert((num_attribs == 0) || (attribs != NULL));
466 
467     if (!(screen->api_mask & (1 << api))) {
468 	*error = __DRI_CTX_ERROR_BAD_API;
469 	return NULL;
470     }
471 
472     switch (api) {
473     case __DRI_API_OPENGL:
474 	mesa_api = API_OPENGL_COMPAT;
475 	break;
476     case __DRI_API_GLES:
477 	mesa_api = API_OPENGLES;
478 	break;
479     case __DRI_API_GLES2:
480     case __DRI_API_GLES3:
481 	mesa_api = API_OPENGLES2;
482 	break;
483     case __DRI_API_OPENGL_CORE:
484         mesa_api = API_OPENGL_CORE;
485         break;
486     default:
487 	*error = __DRI_CTX_ERROR_BAD_API;
488 	return NULL;
489     }
490 
491     for (unsigned i = 0; i < num_attribs; i++) {
492 	switch (attribs[i * 2]) {
493 	case __DRI_CTX_ATTRIB_MAJOR_VERSION:
494             ctx_config.major_version = attribs[i * 2 + 1];
495 	    break;
496 	case __DRI_CTX_ATTRIB_MINOR_VERSION:
497 	    ctx_config.minor_version = attribs[i * 2 + 1];
498 	    break;
499 	case __DRI_CTX_ATTRIB_FLAGS:
500 	    ctx_config.flags = attribs[i * 2 + 1];
501 	    break;
502         case __DRI_CTX_ATTRIB_RESET_STRATEGY:
503             if (attribs[i * 2 + 1] != __DRI_CTX_RESET_NO_NOTIFICATION) {
504                 ctx_config.attribute_mask |=
505                     __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY;
506                 ctx_config.reset_strategy = attribs[i * 2 + 1];
507             } else {
508                 ctx_config.attribute_mask &=
509                     ~__DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY;
510             }
511             break;
512 	case __DRI_CTX_ATTRIB_PRIORITY:
513             ctx_config.attribute_mask |= __DRIVER_CONTEXT_ATTRIB_PRIORITY;
514 	    ctx_config.priority = attribs[i * 2 + 1];
515 	    break;
516         case __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR:
517             if (attribs[i * 2 + 1] != __DRI_CTX_RELEASE_BEHAVIOR_FLUSH) {
518                 ctx_config.attribute_mask |=
519                     __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR;
520                 ctx_config.release_behavior = attribs[i * 2 + 1];
521             } else {
522                 ctx_config.attribute_mask &=
523                     ~__DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR;
524             }
525             break;
526         case __DRI_CTX_ATTRIB_NO_ERROR:
527             if (attribs[i * 2 + 1] != 0) {
528                ctx_config.attribute_mask |=
529                   __DRIVER_CONTEXT_ATTRIB_NO_ERROR;
530                ctx_config.no_error = attribs[i * 2 + 1];
531             } else {
532                ctx_config.attribute_mask &=
533                   ~__DRIVER_CONTEXT_ATTRIB_NO_ERROR;
534             }
535             break;
536 	default:
537 	    /* We can't create a context that satisfies the requirements of an
538 	     * attribute that we don't understand.  Return failure.
539 	     */
540 	    assert(!"Should not get here.");
541 	    *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
542 	    return NULL;
543 	}
544     }
545 
546     /* The specific Mesa driver may not support the GL_ARB_compatibilty
547      * extension or the compatibility profile.  In that case, we treat an
548      * API_OPENGL_COMPAT 3.1 as API_OPENGL_CORE. We reject API_OPENGL_COMPAT
549      * 3.2+ in any case.
550      */
551     if (mesa_api == API_OPENGL_COMPAT &&
552         ctx_config.major_version == 3 && ctx_config.minor_version == 1 &&
553         screen->max_gl_compat_version < 31)
554        mesa_api = API_OPENGL_CORE;
555 
556     /* The latest version of EGL_KHR_create_context spec says:
557      *
558      *     "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
559      *     EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
560      *     [...] This bit is supported for OpenGL and OpenGL ES contexts.
561      *
562      * No other EGL_CONTEXT_OPENGL_*_BIT is legal for an ES context.
563      *
564      * However, Mesa's EGL layer translates the context attribute
565      * EGL_CONTEXT_OPENGL_ROBUST_ACCESS into the context flag
566      * __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS.  That attribute is legal for ES
567      * (with EGL 1.5 or EGL_EXT_create_context_robustness) and GL (only with
568      * EGL 1.5).
569      *
570      * From the EGL_EXT_create_context_robustness spec:
571      *
572      *     This extension is written against the OpenGL ES 2.0 Specification
573      *     but can apply to OpenGL ES 1.1 and up.
574      *
575      * From the EGL 1.5 (2014.08.27) spec, p55:
576      *
577      *     If the EGL_CONTEXT_OPENGL_ROBUST_ACCESS attribute is set to
578      *     EGL_TRUE, a context supporting robust buffer access will be created.
579      *     OpenGL contexts must support the GL_ARB_robustness extension, or
580      *     equivalent core API functional- ity. OpenGL ES contexts must support
581      *     the GL_EXT_robustness extension, or equivalent core API
582      *     functionality.
583      */
584     if (mesa_api != API_OPENGL_COMPAT
585         && mesa_api != API_OPENGL_CORE
586         && (ctx_config.flags & ~(__DRI_CTX_FLAG_DEBUG |
587                                  __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS))) {
588 	*error = __DRI_CTX_ERROR_BAD_FLAG;
589 	return NULL;
590     }
591 
592     /* There are no forward-compatible contexts before OpenGL 3.0.  The
593      * GLX_ARB_create_context spec says:
594      *
595      *     "Forward-compatible contexts are defined only for OpenGL versions
596      *     3.0 and later."
597      *
598      * Forward-looking contexts are supported by silently converting the
599      * requested API to API_OPENGL_CORE.
600      *
601      * In Mesa, a debug context is the same as a regular context.
602      */
603     if ((ctx_config.flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) {
604        mesa_api = API_OPENGL_CORE;
605     }
606 
607     const uint32_t allowed_flags = (__DRI_CTX_FLAG_DEBUG
608                                     | __DRI_CTX_FLAG_FORWARD_COMPATIBLE
609                                     | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS
610                                     | __DRI_CTX_FLAG_RESET_ISOLATION);
611     if (ctx_config.flags & ~allowed_flags) {
612 	*error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
613 	return NULL;
614     }
615 
616     if (!validate_context_version(screen, mesa_api,
617                                   ctx_config.major_version,
618                                   ctx_config.minor_version,
619                                   error))
620        return NULL;
621 
622     context = calloc(1, sizeof *context);
623     if (!context) {
624 	*error = __DRI_CTX_ERROR_NO_MEMORY;
625 	return NULL;
626     }
627 
628     context->loaderPrivate = data;
629 
630     context->driScreenPriv = screen;
631     context->driDrawablePriv = NULL;
632     context->driReadablePriv = NULL;
633 
634     if (!dri_create_context(mesa_api, modes, context, &ctx_config, error,
635                             shareCtx)) {
636         free(context);
637         return NULL;
638     }
639 
640     *error = __DRI_CTX_ERROR_SUCCESS;
641     return context;
642 }
643 
644 static __DRIcontext *
driCreateNewContextForAPI(__DRIscreen * screen,int api,const __DRIconfig * config,__DRIcontext * shared,void * data)645 driCreateNewContextForAPI(__DRIscreen *screen, int api,
646                           const __DRIconfig *config,
647                           __DRIcontext *shared, void *data)
648 {
649     unsigned error;
650 
651     return driCreateContextAttribs(screen, api, config, shared, 0, NULL,
652                                    &error, data);
653 }
654 
655 static __DRIcontext *
driCreateNewContext(__DRIscreen * screen,const __DRIconfig * config,__DRIcontext * shared,void * data)656 driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
657                     __DRIcontext *shared, void *data)
658 {
659     return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
660                                      config, shared, data);
661 }
662 
663 /**
664  * Destroy the per-context private information.
665  *
666  * \internal
667  * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
668  * drmDestroyContext(), and finally frees \p contextPrivate.
669  */
670 static void
driDestroyContext(__DRIcontext * pcp)671 driDestroyContext(__DRIcontext *pcp)
672 {
673     if (pcp) {
674 	dri_destroy_context(pcp);
675 	free(pcp);
676     }
677 }
678 
679 static int
driCopyContext(__DRIcontext * dest,__DRIcontext * src,unsigned long mask)680 driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
681 {
682     (void) dest;
683     (void) src;
684     (void) mask;
685     return GL_FALSE;
686 }
687 
688 /*@}*/
689 
690 
691 /*****************************************************************/
692 /** \name Context (un)binding functions                          */
693 /*****************************************************************/
694 /*@{*/
695 
696 static void dri_get_drawable(__DRIdrawable *pdp);
697 static void dri_put_drawable(__DRIdrawable *pdp);
698 
699 /**
700  * This function takes both a read buffer and a draw buffer.  This is needed
701  * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
702  * function.
703  */
driBindContext(__DRIcontext * pcp,__DRIdrawable * pdp,__DRIdrawable * prp)704 static int driBindContext(__DRIcontext *pcp,
705 			  __DRIdrawable *pdp,
706 			  __DRIdrawable *prp)
707 {
708     /*
709     ** Assume error checking is done properly in glXMakeCurrent before
710     ** calling driUnbindContext.
711     */
712 
713     if (!pcp)
714 	return GL_FALSE;
715 
716     /* Bind the drawable to the context */
717     pcp->driDrawablePriv = pdp;
718     pcp->driReadablePriv = prp;
719     if (pdp) {
720 	pdp->driContextPriv = pcp;
721 	dri_get_drawable(pdp);
722     }
723     if (prp && pdp != prp) {
724 	dri_get_drawable(prp);
725     }
726 
727     return dri_make_current(pcp, pdp, prp);
728 }
729 
730 /**
731  * Unbind context.
732  *
733  * \param scrn the screen.
734  * \param gc context.
735  *
736  * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
737  *
738  * \internal
739  * This function calls __DriverAPIRec::UnbindContext, and then decrements
740  * __DRIdrawableRec::refcount which must be non-zero for a successful
741  * return.
742  *
743  * While casting the opaque private pointers associated with the parameters
744  * into their respective real types it also assures they are not \c NULL.
745  */
driUnbindContext(__DRIcontext * pcp)746 static int driUnbindContext(__DRIcontext *pcp)
747 {
748     __DRIdrawable *pdp;
749     __DRIdrawable *prp;
750 
751     /*
752     ** Assume error checking is done properly in glXMakeCurrent before
753     ** calling driUnbindContext.
754     */
755 
756     if (pcp == NULL)
757 	return GL_FALSE;
758 
759     /*
760     ** Call dri_unbind_context before checking for valid drawables
761     ** to handle surfaceless contexts properly.
762     */
763     dri_unbind_context(pcp);
764 
765     pdp = pcp->driDrawablePriv;
766     prp = pcp->driReadablePriv;
767 
768     /* already unbound */
769     if (!pdp && !prp)
770 	return GL_TRUE;
771 
772     assert(pdp);
773     if (pdp->refcount == 0) {
774 	/* ERROR!!! */
775 	return GL_FALSE;
776     }
777 
778     dri_put_drawable(pdp);
779 
780     if (prp != pdp) {
781 	if (prp->refcount == 0) {
782 	    /* ERROR!!! */
783 	    return GL_FALSE;
784 	}
785 
786 	dri_put_drawable(prp);
787     }
788 
789     pcp->driDrawablePriv = NULL;
790     pcp->driReadablePriv = NULL;
791 
792     return GL_TRUE;
793 }
794 
795 /*@}*/
796 
797 
dri_get_drawable(__DRIdrawable * pdp)798 static void dri_get_drawable(__DRIdrawable *pdp)
799 {
800     pdp->refcount++;
801 }
802 
dri_put_drawable(__DRIdrawable * pdp)803 static void dri_put_drawable(__DRIdrawable *pdp)
804 {
805     if (pdp) {
806 	pdp->refcount--;
807 	if (pdp->refcount)
808 	    return;
809 
810 	pdp->driScreenPriv->driver->DestroyBuffer(pdp);
811 	free(pdp);
812     }
813 }
814 
815 static __DRIdrawable *
driCreateNewDrawable(__DRIscreen * screen,const __DRIconfig * config,void * data)816 driCreateNewDrawable(__DRIscreen *screen,
817                      const __DRIconfig *config,
818                      void *data)
819 {
820     __DRIdrawable *pdraw;
821 
822     assert(data != NULL);
823 
824     pdraw = malloc(sizeof *pdraw);
825     if (!pdraw)
826 	return NULL;
827 
828     pdraw->loaderPrivate = data;
829 
830     pdraw->driScreenPriv = screen;
831     pdraw->driContextPriv = NULL;
832     pdraw->refcount = 0;
833     pdraw->lastStamp = 0;
834     pdraw->w = 0;
835     pdraw->h = 0;
836 
837     dri_get_drawable(pdraw);
838 
839     if (!screen->driver->CreateBuffer(screen, pdraw, &config->modes,
840                                       GL_FALSE)) {
841        free(pdraw);
842        return NULL;
843     }
844 
845     pdraw->dri2.stamp = pdraw->lastStamp + 1;
846 
847     return pdraw;
848 }
849 
850 static void
driDestroyDrawable(__DRIdrawable * pdp)851 driDestroyDrawable(__DRIdrawable *pdp)
852 {
853     /*
854      * The loader's data structures are going away, even if pdp itself stays
855      * around for the time being because it is currently bound. This happens
856      * when a currently bound GLX pixmap is destroyed.
857      *
858      * Clear out the pointer back into the loader's data structures to avoid
859      * accessing an outdated pointer.
860      */
861     pdp->loaderPrivate = NULL;
862 
863     dri_put_drawable(pdp);
864 }
865 
866 static __DRIbuffer *
dri2AllocateBuffer(__DRIscreen * screen,unsigned int attachment,unsigned int format,int width,int height)867 dri2AllocateBuffer(__DRIscreen *screen,
868 		   unsigned int attachment, unsigned int format,
869 		   int width, int height)
870 {
871     return screen->driver->AllocateBuffer(screen, attachment, format,
872                                           width, height);
873 }
874 
875 static void
dri2ReleaseBuffer(__DRIscreen * screen,__DRIbuffer * buffer)876 dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
877 {
878     screen->driver->ReleaseBuffer(screen, buffer);
879 }
880 
881 
882 static int
dri2ConfigQueryb(__DRIscreen * screen,const char * var,unsigned char * val)883 dri2ConfigQueryb(__DRIscreen *screen, const char *var, unsigned char *val)
884 {
885    if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
886       return -1;
887 
888    *val = driQueryOptionb(&screen->optionCache, var);
889 
890    return 0;
891 }
892 
893 static int
dri2ConfigQueryi(__DRIscreen * screen,const char * var,int * val)894 dri2ConfigQueryi(__DRIscreen *screen, const char *var, int *val)
895 {
896    if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
897        !driCheckOption(&screen->optionCache, var, DRI_ENUM))
898       return -1;
899 
900     *val = driQueryOptioni(&screen->optionCache, var);
901 
902     return 0;
903 }
904 
905 static int
dri2ConfigQueryf(__DRIscreen * screen,const char * var,float * val)906 dri2ConfigQueryf(__DRIscreen *screen, const char *var, float *val)
907 {
908    if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
909       return -1;
910 
911     *val = driQueryOptionf(&screen->optionCache, var);
912 
913     return 0;
914 }
915 
916 static int
dri2ConfigQuerys(__DRIscreen * screen,const char * var,char ** val)917 dri2ConfigQuerys(__DRIscreen *screen, const char *var, char **val)
918 {
919    if (!driCheckOption(&screen->optionCache, var, DRI_STRING))
920       return -1;
921 
922     *val = driQueryOptionstr(&screen->optionCache, var);
923 
924     return 0;
925 }
926 
927 static unsigned int
driGetAPIMask(__DRIscreen * screen)928 driGetAPIMask(__DRIscreen *screen)
929 {
930     return screen->api_mask;
931 }
932 
933 /**
934  * swrast swapbuffers entrypoint.
935  *
936  * DRI2 implements this inside the loader with only flushes handled by the
937  * driver.
938  */
939 static void
driSwapBuffers(__DRIdrawable * pdp)940 driSwapBuffers(__DRIdrawable *pdp)
941 {
942     assert(pdp->driScreenPriv->swrast_loader);
943 
944     pdp->driScreenPriv->driver->SwapBuffers(pdp);
945 }
946 
947 /** Core interface */
948 const __DRIcoreExtension driCoreExtension = {
949     .base = { __DRI_CORE, 2 },
950 
951     .createNewScreen            = NULL,
952     .destroyScreen              = driDestroyScreen,
953     .getExtensions              = driGetExtensions,
954     .getConfigAttrib            = driGetConfigAttrib,
955     .indexConfigAttrib          = driIndexConfigAttrib,
956     .createNewDrawable          = NULL,
957     .destroyDrawable            = driDestroyDrawable,
958     .swapBuffers                = driSwapBuffers, /* swrast */
959     .createNewContext           = driCreateNewContext, /* swrast */
960     .copyContext                = driCopyContext,
961     .destroyContext             = driDestroyContext,
962     .bindContext                = driBindContext,
963     .unbindContext              = driUnbindContext
964 };
965 
966 #if HAVE_DRI2
967 
968 /** DRI2 interface */
969 const __DRIdri2Extension driDRI2Extension = {
970     .base = { __DRI_DRI2, 4 },
971 
972     .createNewScreen            = dri2CreateNewScreen,
973     .createNewDrawable          = driCreateNewDrawable,
974     .createNewContext           = driCreateNewContext,
975     .getAPIMask                 = driGetAPIMask,
976     .createNewContextForAPI     = driCreateNewContextForAPI,
977     .allocateBuffer             = dri2AllocateBuffer,
978     .releaseBuffer              = dri2ReleaseBuffer,
979     .createContextAttribs       = driCreateContextAttribs,
980     .createNewScreen2           = driCreateNewScreen2,
981 };
982 
983 const __DRIdri2Extension swkmsDRI2Extension = {
984     .base = { __DRI_DRI2, 4 },
985 
986     .createNewScreen            = swkmsCreateNewScreen,
987     .createNewDrawable          = driCreateNewDrawable,
988     .createNewContext           = driCreateNewContext,
989     .getAPIMask                 = driGetAPIMask,
990     .createNewContextForAPI     = driCreateNewContextForAPI,
991     .allocateBuffer             = dri2AllocateBuffer,
992     .releaseBuffer              = dri2ReleaseBuffer,
993     .createContextAttribs       = driCreateContextAttribs,
994     .createNewScreen2           = driCreateNewScreen2,
995 };
996 
997 #endif
998 
999 const __DRIswrastExtension driSWRastExtension = {
1000     .base = { __DRI_SWRAST, 4 },
1001 
1002     .createNewScreen            = driSWRastCreateNewScreen,
1003     .createNewDrawable          = driCreateNewDrawable,
1004     .createNewContextForAPI     = driCreateNewContextForAPI,
1005     .createContextAttribs       = driCreateContextAttribs,
1006     .createNewScreen2           = driSWRastCreateNewScreen2,
1007 };
1008 
1009 const __DRI2configQueryExtension dri2ConfigQueryExtension = {
1010    .base = { __DRI2_CONFIG_QUERY, 2 },
1011 
1012    .configQueryb        = dri2ConfigQueryb,
1013    .configQueryi        = dri2ConfigQueryi,
1014    .configQueryf        = dri2ConfigQueryf,
1015    .configQuerys        = dri2ConfigQuerys,
1016 };
1017 
1018 const __DRI2flushControlExtension dri2FlushControlExtension = {
1019    .base = { __DRI2_FLUSH_CONTROL, 1 }
1020 };
1021 
1022 /*
1023  * Note: the first match is returned, which is important for formats like
1024  * __DRI_IMAGE_FORMAT_R8 which maps to both MESA_FORMAT_{R,L}_UNORM8
1025  */
1026 static const struct {
1027    uint32_t    image_format;
1028    mesa_format mesa_format;
1029    GLenum internal_format;
1030 } format_mapping[] = {
1031    {
1032       .image_format    = __DRI_IMAGE_FORMAT_RGB565,
1033       .mesa_format     =        MESA_FORMAT_B5G6R5_UNORM,
1034       .internal_format =        GL_RGB565,
1035    },
1036    {
1037       .image_format    = __DRI_IMAGE_FORMAT_ARGB1555,
1038       .mesa_format     =        MESA_FORMAT_B5G5R5A1_UNORM,
1039       .internal_format =        GL_RGB5_A1,
1040    },
1041    {
1042       .image_format    = __DRI_IMAGE_FORMAT_XRGB8888,
1043       .mesa_format     =        MESA_FORMAT_B8G8R8X8_UNORM,
1044       .internal_format =        GL_RGB8,
1045    },
1046    {
1047       .image_format    = __DRI_IMAGE_FORMAT_ABGR16161616F,
1048       .mesa_format     =        MESA_FORMAT_RGBA_FLOAT16,
1049       .internal_format =        GL_RGBA16F,
1050    },
1051    {
1052       .image_format    = __DRI_IMAGE_FORMAT_XBGR16161616F,
1053       .mesa_format     =        MESA_FORMAT_RGBX_FLOAT16,
1054       .internal_format =        GL_RGBA16F,
1055    },
1056    {
1057       .image_format    = __DRI_IMAGE_FORMAT_ABGR16161616,
1058       .mesa_format     =        MESA_FORMAT_RGBA_UNORM16,
1059       .internal_format =        GL_RGBA16,
1060    },
1061    {
1062       .image_format    = __DRI_IMAGE_FORMAT_XBGR16161616,
1063       .mesa_format     =        MESA_FORMAT_RGBX_UNORM16,
1064       .internal_format =        GL_RGBA16,
1065    },
1066    {
1067       .image_format    = __DRI_IMAGE_FORMAT_ARGB2101010,
1068       .mesa_format     =        MESA_FORMAT_B10G10R10A2_UNORM,
1069       .internal_format =        GL_RGB10_A2,
1070    },
1071    {
1072       .image_format    = __DRI_IMAGE_FORMAT_XRGB2101010,
1073       .mesa_format     =        MESA_FORMAT_B10G10R10X2_UNORM,
1074       .internal_format =        GL_RGB10_A2,
1075    },
1076    {
1077       .image_format    = __DRI_IMAGE_FORMAT_ABGR2101010,
1078       .mesa_format     =        MESA_FORMAT_R10G10B10A2_UNORM,
1079       .internal_format =        GL_RGB10_A2,
1080    },
1081    {
1082       .image_format    = __DRI_IMAGE_FORMAT_XBGR2101010,
1083       .mesa_format     =        MESA_FORMAT_R10G10B10X2_UNORM,
1084       .internal_format =        GL_RGB10_A2,
1085    },
1086    {
1087       .image_format    = __DRI_IMAGE_FORMAT_ARGB8888,
1088       .mesa_format     =        MESA_FORMAT_B8G8R8A8_UNORM,
1089       .internal_format =        GL_RGBA8,
1090    },
1091    {
1092       .image_format    = __DRI_IMAGE_FORMAT_ABGR8888,
1093       .mesa_format     =        MESA_FORMAT_R8G8B8A8_UNORM,
1094       .internal_format =        GL_RGBA8,
1095    },
1096    {
1097       .image_format    = __DRI_IMAGE_FORMAT_XBGR8888,
1098       .mesa_format     =        MESA_FORMAT_R8G8B8X8_UNORM,
1099       .internal_format =        GL_RGB8,
1100    },
1101    {
1102       .image_format    = __DRI_IMAGE_FORMAT_R8,
1103       .mesa_format     =        MESA_FORMAT_R_UNORM8,
1104       .internal_format =        GL_R8,
1105    },
1106    {
1107       .image_format    = __DRI_IMAGE_FORMAT_R8,
1108       .mesa_format     =        MESA_FORMAT_L_UNORM8,
1109       .internal_format =        GL_R8,
1110    },
1111 #if UTIL_ARCH_LITTLE_ENDIAN
1112    {
1113       .image_format    = __DRI_IMAGE_FORMAT_GR88,
1114       .mesa_format     =        MESA_FORMAT_RG_UNORM8,
1115       .internal_format =        GL_RG8,
1116    },
1117    {
1118       .image_format    = __DRI_IMAGE_FORMAT_GR88,
1119       .mesa_format     =        MESA_FORMAT_LA_UNORM8,
1120       .internal_format =        GL_RG8,
1121    },
1122 #endif
1123    {
1124       .image_format    = __DRI_IMAGE_FORMAT_SABGR8,
1125       .mesa_format     =        MESA_FORMAT_R8G8B8A8_SRGB,
1126       .internal_format =        GL_SRGB8_ALPHA8,
1127    },
1128    {
1129       .image_format    = __DRI_IMAGE_FORMAT_SARGB8,
1130       .mesa_format     =        MESA_FORMAT_B8G8R8A8_SRGB,
1131       .internal_format =        GL_SRGB8_ALPHA8,
1132    },
1133    {
1134       .image_format = __DRI_IMAGE_FORMAT_SXRGB8,
1135       .mesa_format  =           MESA_FORMAT_B8G8R8X8_SRGB,
1136       .internal_format =        GL_SRGB8_ALPHA8,
1137    },
1138    {
1139       .image_format    = __DRI_IMAGE_FORMAT_R16,
1140       .mesa_format     =        MESA_FORMAT_R_UNORM16,
1141       .internal_format =        GL_R16,
1142    },
1143    {
1144       .image_format    = __DRI_IMAGE_FORMAT_R16,
1145       .mesa_format     =        MESA_FORMAT_L_UNORM16,
1146       .internal_format =        GL_R16,
1147    },
1148 #if UTIL_ARCH_LITTLE_ENDIAN
1149    {
1150       .image_format    = __DRI_IMAGE_FORMAT_GR1616,
1151       .mesa_format     =        MESA_FORMAT_RG_UNORM16,
1152       .internal_format =        GL_RG16,
1153    },
1154    {
1155       .image_format    = __DRI_IMAGE_FORMAT_GR1616,
1156       .mesa_format     =        MESA_FORMAT_LA_UNORM16,
1157       .internal_format =        GL_RG16,
1158    },
1159 #endif
1160 };
1161 
1162 uint32_t
driGLFormatToImageFormat(mesa_format format)1163 driGLFormatToImageFormat(mesa_format format)
1164 {
1165    for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++)
1166       if (format_mapping[i].mesa_format == format)
1167          return format_mapping[i].image_format;
1168 
1169    return __DRI_IMAGE_FORMAT_NONE;
1170 }
1171 
1172 uint32_t
driGLFormatToSizedInternalGLFormat(mesa_format format)1173 driGLFormatToSizedInternalGLFormat(mesa_format format)
1174 {
1175    for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++)
1176       if (format_mapping[i].mesa_format == format)
1177          return format_mapping[i].internal_format;
1178 
1179    return GL_NONE;
1180 }
1181 
1182 mesa_format
driImageFormatToGLFormat(uint32_t image_format)1183 driImageFormatToGLFormat(uint32_t image_format)
1184 {
1185    for (size_t i = 0; i < ARRAY_SIZE(format_mapping); i++)
1186       if (format_mapping[i].image_format == image_format)
1187          return format_mapping[i].mesa_format;
1188 
1189    return MESA_FORMAT_NONE;
1190 }
1191 
1192 /** Image driver interface */
1193 const __DRIimageDriverExtension driImageDriverExtension = {
1194     .base = { __DRI_IMAGE_DRIVER, 1 },
1195 
1196     .createNewScreen2           = driCreateNewScreen2,
1197     .createNewDrawable          = driCreateNewDrawable,
1198     .getAPIMask                 = driGetAPIMask,
1199     .createContextAttribs       = driCreateContextAttribs,
1200 };
1201