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
53driOptionDescription __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
69static void
70setupLoaderExtensions(__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 */
102static __DRIscreen *
103driCreateNewScreen2(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
178static __DRIscreen *
179dri2CreateNewScreen(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
188static __DRIscreen *
189swkmsCreateNewScreen(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. */
199static __DRIscreen *
200driSWRastCreateNewScreen(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
208static __DRIscreen *
209driSWRastCreateNewScreen2(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 */
224static 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
241static 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 */
259static int
260driGetConfigAttribIndex(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 */
374static int
375driGetConfigAttrib(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 */
388static int
389driIndexConfigAttrib(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
400static bool
401validate_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
444static __DRIcontext *
445driCreateContextAttribs(__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
644static __DRIcontext *
645driCreateNewContextForAPI(__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
655static __DRIcontext *
656driCreateNewContext(__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 */
670static void
671driDestroyContext(__DRIcontext *pcp)
672{
673    if (pcp) {
674	dri_destroy_context(pcp);
675	free(pcp);
676    }
677}
678
679static int
680driCopyContext(__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
696static void dri_get_drawable(__DRIdrawable *pdp);
697static 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 */
704static 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 */
746static 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
798static void dri_get_drawable(__DRIdrawable *pdp)
799{
800    pdp->refcount++;
801}
802
803static 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
815static __DRIdrawable *
816driCreateNewDrawable(__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
850static void
851driDestroyDrawable(__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
866static __DRIbuffer *
867dri2AllocateBuffer(__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
875static void
876dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
877{
878    screen->driver->ReleaseBuffer(screen, buffer);
879}
880
881
882static int
883dri2ConfigQueryb(__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
893static int
894dri2ConfigQueryi(__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
905static int
906dri2ConfigQueryf(__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
916static int
917dri2ConfigQuerys(__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
927static unsigned int
928driGetAPIMask(__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 */
939static void
940driSwapBuffers(__DRIdrawable *pdp)
941{
942    assert(pdp->driScreenPriv->swrast_loader);
943
944    pdp->driScreenPriv->driver->SwapBuffers(pdp);
945}
946
947/** Core interface */
948const __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 */
969const __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
983const __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
999const __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
1009const __DRI2configQueryExtension dri2ConfigQueryExtension = {
1010   .base = { __DRI2_CONFIG_QUERY, 2 },
1011
1012   .configQueryb        = dri2ConfigQueryb,
1013   .configQueryi        = dri2ConfigQueryi,
1014   .configQueryf        = dri2ConfigQueryf,
1015   .configQuerys        = dri2ConfigQuerys,
1016};
1017
1018const __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 */
1026static 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
1162uint32_t
1163driGLFormatToImageFormat(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
1172uint32_t
1173driGLFormatToSizedInternalGLFormat(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
1182mesa_format
1183driImageFormatToGLFormat(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 */
1193const __DRIimageDriverExtension driImageDriverExtension = {
1194    .base = { __DRI_IMAGE_DRIVER, 1 },
1195
1196    .createNewScreen2           = driCreateNewScreen2,
1197    .createNewDrawable          = driCreateNewDrawable,
1198    .getAPIMask                 = driGetAPIMask,
1199    .createContextAttribs       = driCreateContextAttribs,
1200};
1201