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