dri_util.c revision 70f47505a2e5d4cf949b7c2650f3d9f6559bacb3
1aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul/*
2aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * (C) Copyright IBM Corporation 2002, 2004
3aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * All Rights Reserved.
4aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul *
5aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
6aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * copy of this software and associated documentation files (the "Software"),
7aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * to deal in the Software without restriction, including without limitation
8aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * on the rights to use, copy, modify, merge, publish, distribute, sub
9aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * license, and/or sell copies of the Software, and to permit persons to whom
10aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * the Software is furnished to do so, subject to the following conditions:
11aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul *
12aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * The above copyright notice and this permission notice (including the next
13aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * paragraph) shall be included in all copies or substantial portions of the
14aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * Software.
15aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul *
16aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul * USE OR OTHER DEALINGS IN THE SOFTWARE.
23aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul */
24aec47e7d42ed58a7c63b36cff03c6c8dcfc71538Brian Paul
25680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
26680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \file dri_util.c
27680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI utility functions.
28680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
29680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This module acts as glue between GLX and the actual hardware driver.  A DRI
30680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver doesn't really \e have to use any of this - it's optional.  But, some
31680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * useful stuff is done here that otherwise would have to be duplicated in most
32680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drivers.
33680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
34680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Basically, these utility functions take care of some of the dirty details of
35680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * screen initialization, context creation, context binding, DRM setup, etc.
36680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
37680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These functions are compiled into each DRI driver so libGL.so knows nothing
38680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * about them.
39680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
40680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
41680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
427192c37294964b3f6e1551469f161593ec8f851dGeorge Sapountzis#include <xf86drm.h>
437c46033130b1b4d6098647d85c2710367572e079Ian Romanick#include "dri_util.h"
44c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis#include "utils.h"
4545e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes#include "xmlpool.h"
46ae6e112c69cf42fb81ef4ed5bdeb3b280647f141Eric Anholt#include "../glsl/glsl_parser_extras.h"
4745e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
4845e2b51c853471b79004a954ce3092a253b20b77Jesse BarnesPUBLIC const char __dri2ConfigOptions[] =
4945e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   DRI_CONF_BEGIN
5045e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      DRI_CONF_SECTION_PERFORMANCE
5145e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes         DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
5245e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      DRI_CONF_SECTION_END
5345e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   DRI_CONF_END;
5445e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
5545e2b51c853471b79004a954ce3092a253b20b77Jesse Barnesstatic const uint __dri2NConfigOptions = 1;
56680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
57680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
58c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/** \name Screen handling functions                              */
59c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*****************************************************************/
60c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*@{*/
61c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
62c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic void
63c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge SapountzissetupLoaderExtensions(__DRIscreen *psp,
64c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis		      const __DRIextension **extensions)
65c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
66c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    int i;
67c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
68c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    for (i = 0; extensions[i]; i++) {
69c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
70c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	    psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
71c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
72c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	    psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
73c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0)
74c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	    psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
75c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
76c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
77c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
78c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic __DRIscreen *
79c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisdri2CreateNewScreen(int scrn, int fd,
80c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis		    const __DRIextension **extensions,
81c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis		    const __DRIconfig ***driver_configs, void *data)
82c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
83c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    static const __DRIextension *emptyExtensionList[] = { NULL };
84c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    __DRIscreen *psp;
85c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    drmVersionPtr version;
86c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
87c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp = calloc(1, sizeof(*psp));
88c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (!psp)
89c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	return NULL;
90c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
91c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    setupLoaderExtensions(psp, extensions);
92c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
93c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    version = drmGetVersion(fd);
94c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (version) {
95c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	psp->drm_version.major = version->version_major;
96c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	psp->drm_version.minor = version->version_minor;
97c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	psp->drm_version.patch = version->version_patchlevel;
98c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	drmFreeVersion(version);
99c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
100c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
101cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    psp->loaderPrivate = data;
102cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
103c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->extensions = emptyExtensionList;
104c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->fd = fd;
105c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->myNum = scrn;
106c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
107c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->api_mask = (1 << __DRI_API_OPENGL);
108cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
109c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    *driver_configs = driDriverAPI.InitScreen(psp);
110c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (*driver_configs == NULL) {
111c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	free(psp);
112c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	return NULL;
113c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
114c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
115cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions, __dri2NConfigOptions);
116cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2");
117c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
118c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    return psp;
119c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
120c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
121c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/**
122c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * Destroy the per-screen private information.
123c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis *
124c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * \internal
125c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
126c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * drmClose(), and finally frees \p screenPrivate.
127c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis */
128c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic void driDestroyScreen(__DRIscreen *psp)
129c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
130c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (psp) {
131c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	/* No interaction with the X-server is possible at this point.  This
132c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	 * routine is called after XCloseDisplay, so there is no protocol
133c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	 * stream open to the X-server anymore.
134c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	 */
135c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
136c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis       _mesa_destroy_shader_compiler();
137c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
138cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	driDriverAPI.DestroyScreen(psp);
139c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
140c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	driDestroyOptionCache(&psp->optionCache);
141c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	driDestroyOptionInfo(&psp->optionInfo);
142c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
143c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	free(psp);
144c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
145c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
146c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
147c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic const __DRIextension **driGetExtensions(__DRIscreen *psp)
148c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
149c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    return psp->extensions;
150c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
151c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
152c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*@}*/
153c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
154c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
155c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*****************************************************************/
1569292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/** \name Context handling functions                             */
1579292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*****************************************************************/
1589292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*@{*/
1599292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
1609292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic __DRIcontext *
161d9de33c304d875627937cacbfc21f54a406af726Ian Romanickdri2CreateContextAttribs(__DRIscreen *screen, int api,
162d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 const __DRIconfig *config,
163d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 __DRIcontext *shared,
164d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 unsigned num_attribs,
165d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 const uint32_t *attribs,
166d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 unsigned *error,
167d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 void *data)
1689292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
1699292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    __DRIcontext *context;
1709292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
1719292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
1729292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    gl_api mesa_api;
173d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    unsigned major_version = 1;
174d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    unsigned minor_version = 0;
175d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    uint32_t flags = 0;
176d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
177d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    assert((num_attribs == 0) || (attribs != NULL));
1789292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
179d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    if (!(screen->api_mask & (1 << api))) {
180d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	*error = __DRI_CTX_ERROR_BAD_API;
1819292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	return NULL;
182d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
1839292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
1849292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    switch (api) {
1859292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    case __DRI_API_OPENGL:
186d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	mesa_api = API_OPENGL;
187d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	break;
1889292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    case __DRI_API_GLES:
189d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	mesa_api = API_OPENGLES;
190d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	break;
1919292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    case __DRI_API_GLES2:
192d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	mesa_api = API_OPENGLES2;
193d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	break;
194d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    case __DRI_API_OPENGL_CORE:
19570f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick        mesa_api = API_OPENGL_CORE;
19670f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick        break;
1979292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    default:
198d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	*error = __DRI_CTX_ERROR_BAD_API;
199d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	return NULL;
200d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
201d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
202d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    for (unsigned i = 0; i < num_attribs; i++) {
203d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	switch (attribs[i * 2]) {
204d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	case __DRI_CTX_ATTRIB_MAJOR_VERSION:
205d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    major_version = attribs[i * 2 + 1];
206d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    break;
207d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	case __DRI_CTX_ATTRIB_MINOR_VERSION:
208d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    minor_version = attribs[i * 2 + 1];
209d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    break;
210d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	case __DRI_CTX_ATTRIB_FLAGS:
211d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    flags = attribs[i * 2 + 1];
212d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    break;
213d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	default:
214d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    /* We can't create a context that satisfies the requirements of an
215d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	     * attribute that we don't understand.  Return failure.
216d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	     */
217e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick	    assert(!"Should not get here.");
218e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick	    *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
219d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    return NULL;
220d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	}
221d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
222d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
22370f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick    /* Mesa does not support the GL_ARB_compatibilty extension or the
22470f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick     * compatibility profile.  This means that we treat a API_OPENGL 3.1 as
22570f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick     * API_OPENGL_CORE and reject API_OPENGL 3.2+.
22670f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick     */
22770f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick    if (mesa_api == API_OPENGL && major_version == 3 && minor_version == 1)
22870f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick       mesa_api = API_OPENGL_CORE;
22970f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick
23070f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick    if (mesa_api == API_OPENGL
23170f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick        && ((major_version > 3)
23270f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick            || (major_version == 3 && minor_version >= 2))) {
23370f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick       *error = __DRI_CTX_ERROR_BAD_API;
23470f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick       return NULL;
23570f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick    }
23670f47505a2e5d4cf949b7c2650f3d9f6559bacb3Ian Romanick
23763adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick    /* The EGL_KHR_create_context spec says:
23863adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     *
23963adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     *     "Flags are only defined for OpenGL context creation, and specifying
24063adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     *     a flags value other than zero for other types of contexts,
24163adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     *     including OpenGL ES contexts, will generate an error."
24263adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     *
24363adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     * The GLX_EXT_create_context_es2_profile specification doesn't say
24463adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     * anything specific about this case.  However, none of the known flags
24563adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     * have any meaning in an ES context, so this seems safe.
24663adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick     */
24763adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick    if (mesa_api != __DRI_API_OPENGL
24863adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick        && mesa_api != __DRI_API_OPENGL_CORE
24963adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick        && flags != 0) {
25063adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick	*error = __DRI_CTX_ERROR_BAD_FLAG;
25163adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick	return NULL;
25263adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick    }
25363adb6b9eaa723f6bf9603f3f567e04451df857eIan Romanick
254d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    /* There are no forward-compatible contexts before OpenGL 3.0.  The
255d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * GLX_ARB_create_context spec says:
256d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *
257d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *     "Forward-compatible contexts are defined only for OpenGL versions
258d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *     3.0 and later."
259d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *
260d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * Moreover, Mesa can't fulfill the requirements of a forward-looking
261d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * context.  Return failure if a forward-looking context is requested.
262d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *
263d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * In Mesa, a debug context is the same as a regular context.
264d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     */
265e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick    if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) {
266e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick	*error = __DRI_CTX_ERROR_BAD_FLAG;
267e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick	return NULL;
268e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick    }
269e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick
270e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick    if ((flags & ~__DRI_CTX_FLAG_DEBUG) != 0) {
271e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick	*error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
272e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick	return NULL;
2739292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    }
2749292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2759292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    context = malloc(sizeof *context);
276d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    if (!context) {
277d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	*error = __DRI_CTX_ERROR_NO_MEMORY;
2789292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	return NULL;
279d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
2809292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
281cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    context->loaderPrivate = data;
282cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
2839292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    context->driScreenPriv = screen;
2849292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    context->driDrawablePriv = NULL;
285cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    context->driReadablePriv = NULL;
2869292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
287e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick    if (!driDriverAPI.CreateContext(mesa_api, modes, context,
288e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick				    major_version, minor_version,
289e532b6288f01b63d8d8ba8c8dc08292967e65490Ian Romanick				    flags, error, shareCtx) ) {
2909292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis        free(context);
2919292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis        return NULL;
2929292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    }
2939292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
294d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    *error = __DRI_CTX_ERROR_SUCCESS;
2959292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    return context;
2969292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
2979292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
298d9de33c304d875627937cacbfc21f54a406af726Ian Romanickstatic __DRIcontext *
299d9de33c304d875627937cacbfc21f54a406af726Ian Romanickdri2CreateNewContextForAPI(__DRIscreen *screen, int api,
300d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			   const __DRIconfig *config,
301d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			   __DRIcontext *shared, void *data)
302d9de33c304d875627937cacbfc21f54a406af726Ian Romanick{
303d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    unsigned error;
304d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
305d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL,
306596d9f6dd170ec7a4c9ed94dd545b4b3d7c7c07dIan Romanick				    &error, data);
307d9de33c304d875627937cacbfc21f54a406af726Ian Romanick}
3089292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
3099292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic __DRIcontext *
3109292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisdri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
3119292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis		      __DRIcontext *shared, void *data)
3129292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
313cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
314cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis				      config, shared, data);
3159292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
3169292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
3179292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/**
3189292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * Destroy the per-context private information.
3199292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis *
3209292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * \internal
3219292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
3229292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * drmDestroyContext(), and finally frees \p contextPrivate.
3239292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis */
3249292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic void
3259292ab7190b7f5805e1670be63022716035d067eGeorge SapountzisdriDestroyContext(__DRIcontext *pcp)
3269292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
3279292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    if (pcp) {
3289292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	driDriverAPI.DestroyContext(pcp);
3299292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	free(pcp);
3309292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    }
3319292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
3329292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
3339292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic int
3349292ab7190b7f5805e1670be63022716035d067eGeorge SapountzisdriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
3359292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
3369292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    (void) dest;
3379292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    (void) src;
3389292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    (void) mask;
3399292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    return GL_FALSE;
3409292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
3419292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
3429292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*@}*/
3439292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
3449292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
3459292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*****************************************************************/
346680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions                          */
347680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
348680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
349680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3502314021d603afa40321fb7b50881bc85d406c921George Sapountzisstatic void dri_get_drawable(__DRIdrawable *pdp);
3512314021d603afa40321fb7b50881bc85d406c921George Sapountzisstatic void dri_put_drawable(__DRIdrawable *pdp);
3522314021d603afa40321fb7b50881bc85d406c921George Sapountzis
3532314021d603afa40321fb7b50881bc85d406c921George Sapountzis/**
3542314021d603afa40321fb7b50881bc85d406c921George Sapountzis * This function takes both a read buffer and a draw buffer.  This is needed
3552314021d603afa40321fb7b50881bc85d406c921George Sapountzis * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
3562314021d603afa40321fb7b50881bc85d406c921George Sapountzis * function.
3572314021d603afa40321fb7b50881bc85d406c921George Sapountzis */
3582314021d603afa40321fb7b50881bc85d406c921George Sapountzisstatic int driBindContext(__DRIcontext *pcp,
3592314021d603afa40321fb7b50881bc85d406c921George Sapountzis			  __DRIdrawable *pdp,
3602314021d603afa40321fb7b50881bc85d406c921George Sapountzis			  __DRIdrawable *prp)
3612314021d603afa40321fb7b50881bc85d406c921George Sapountzis{
3622314021d603afa40321fb7b50881bc85d406c921George Sapountzis    /*
3632314021d603afa40321fb7b50881bc85d406c921George Sapountzis    ** Assume error checking is done properly in glXMakeCurrent before
3642314021d603afa40321fb7b50881bc85d406c921George Sapountzis    ** calling driUnbindContext.
3652314021d603afa40321fb7b50881bc85d406c921George Sapountzis    */
3662314021d603afa40321fb7b50881bc85d406c921George Sapountzis
3672314021d603afa40321fb7b50881bc85d406c921George Sapountzis    if (!pcp)
3682314021d603afa40321fb7b50881bc85d406c921George Sapountzis	return GL_FALSE;
3692314021d603afa40321fb7b50881bc85d406c921George Sapountzis
3702314021d603afa40321fb7b50881bc85d406c921George Sapountzis    /* Bind the drawable to the context */
3712314021d603afa40321fb7b50881bc85d406c921George Sapountzis    pcp->driDrawablePriv = pdp;
3722314021d603afa40321fb7b50881bc85d406c921George Sapountzis    pcp->driReadablePriv = prp;
3732314021d603afa40321fb7b50881bc85d406c921George Sapountzis    if (pdp) {
3742314021d603afa40321fb7b50881bc85d406c921George Sapountzis	pdp->driContextPriv = pcp;
3752314021d603afa40321fb7b50881bc85d406c921George Sapountzis	dri_get_drawable(pdp);
3762314021d603afa40321fb7b50881bc85d406c921George Sapountzis    }
3772314021d603afa40321fb7b50881bc85d406c921George Sapountzis    if (prp && pdp != prp) {
3782314021d603afa40321fb7b50881bc85d406c921George Sapountzis	dri_get_drawable(prp);
3792314021d603afa40321fb7b50881bc85d406c921George Sapountzis    }
3802314021d603afa40321fb7b50881bc85d406c921George Sapountzis
3812314021d603afa40321fb7b50881bc85d406c921George Sapountzis    return driDriverAPI.MakeCurrent(pcp, pdp, prp);
3822314021d603afa40321fb7b50881bc85d406c921George Sapountzis}
3832314021d603afa40321fb7b50881bc85d406c921George Sapountzis
384680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
385680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context.
386680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
387aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg * \param scrn the screen.
388680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context.
389680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
390680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
391680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
392680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
393680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements
394d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * __DRIdrawableRec::refcount which must be non-zero for a successful
395680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return.
396680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
397680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters
398680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL.
399680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
400e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driUnbindContext(__DRIcontext *pcp)
401680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
402418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *pdp;
403418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *prp;
404680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
405680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
406680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
407c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    ** calling driUnbindContext.
408680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
409680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
410e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (pcp == NULL)
411cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	return GL_FALSE;
412680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
413418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pdp = pcp->driDrawablePriv;
414418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    prp = pcp->driReadablePriv;
415680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
416418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* already unbound */
417418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (!pdp && !prp)
418cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	return GL_TRUE;
419cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
420875a757ddd103722cfe9a2b21035024aa5a23d32George Sapountzis    driDriverAPI.UnbindContext(pcp);
421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
422cab77711b3e8d398393677bcefcd413f50503a64Vinson Lee    assert(pdp);
423418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (pdp->refcount == 0) {
424418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	/* ERROR!!! */
425418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	return GL_FALSE;
426418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
427418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
428418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    dri_put_drawable(pdp);
429418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
430418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (prp != pdp) {
431cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	if (prp->refcount == 0) {
432418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    /* ERROR!!! */
433418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    return GL_FALSE;
434418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	}
435418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
436cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	dri_put_drawable(prp);
437418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
438418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
439418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* XXX this is disabled so that if we call SwapBuffers on an unbound
440418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * window we can determine the last context bound to the window and
441418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * use that context's lock. (BrianP, 2-Dec-2000)
442418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     */
443cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pcp->driDrawablePriv = NULL;
444cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pcp->driReadablePriv = NULL;
445418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
446680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
447680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
448680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4492314021d603afa40321fb7b50881bc85d406c921George Sapountzis/*@}*/
450680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
451680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4522fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzisstatic void dri_get_drawable(__DRIdrawable *pdp)
4532fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis{
4542fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    pdp->refcount++;
4552fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis}
4562fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
4572fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzisstatic void dri_put_drawable(__DRIdrawable *pdp)
4582fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis{
4592fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    if (pdp) {
4602fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	pdp->refcount--;
4612fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	if (pdp->refcount)
4622fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	    return;
4632fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
464cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	driDriverAPI.DestroyBuffer(pdp);
4652fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	free(pdp);
4662fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    }
4672fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis}
4682fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
469e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
470f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsbergdri2CreateNewDrawable(__DRIscreen *screen,
471f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg		      const __DRIconfig *config,
472cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis		      void *data)
473680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
474f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    __DRIdrawable *pdraw;
475680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
476f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw = malloc(sizeof *pdraw);
477f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    if (!pdraw)
478680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
479680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
480cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pdraw->loaderPrivate = data;
481cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
482cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pdraw->driScreenPriv = screen;
483f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->driContextPriv = NULL;
484cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pdraw->refcount = 0;
485f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->lastStamp = 0;
486f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->w = 0;
487f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->h = 0;
488f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg
489cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    dri_get_drawable(pdraw);
490cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
491cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    if (!driDriverAPI.CreateBuffer(screen, pdraw, &config->modes, GL_FALSE)) {
492f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg       free(pdraw);
493680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       return NULL;
494680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
495680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
496e9beaf65fdaf82a7845cbe176f353ddb6b8466c7Kristian Høgsberg    pdraw->dri2.stamp = pdraw->lastStamp + 1;
49761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
498e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdraw;
499680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
500680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
5012fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzisstatic void
5022fbba6bb906a4389de64cc6e961b531d8cd5c495George SapountzisdriDestroyDrawable(__DRIdrawable *pdp)
5032fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis{
5042fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    dri_put_drawable(pdp);
5052fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis}
5062fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
5071b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic __DRIbuffer *
5081b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2AllocateBuffer(__DRIscreen *screen,
5091b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   unsigned int attachment, unsigned int format,
5101b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   int width, int height)
5111b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
512875a757ddd103722cfe9a2b21035024aa5a23d32George Sapountzis    return driDriverAPI.AllocateBuffer(screen, attachment, format,
513875a757ddd103722cfe9a2b21035024aa5a23d32George Sapountzis				       width, height);
5141b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
5151b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
5161b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic void
5171b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
5181b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
519cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    driDriverAPI.ReleaseBuffer(screen, buffer);
5201b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
5211b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
5221b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
523234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
524234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val)
525234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
526234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
527234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
528234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
529234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   *val = driQueryOptionb(&screen->optionCache, var);
530234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
531234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   return 0;
532234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
533234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
534234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
535234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val)
536234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
537234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
538234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes       !driCheckOption(&screen->optionCache, var, DRI_ENUM))
539234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
540234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
541234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptioni(&screen->optionCache, var);
542234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
543234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
544234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
545234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
546234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
547234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
548234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
549234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
550234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
551234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
552234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptionf(&screen->optionCache, var);
553234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
554234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
555234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
556234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
557a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic unsigned int
558a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2GetAPIMask(__DRIscreen *screen)
559a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
560a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return screen->api_mask;
561a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
562a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
563e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
564f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Core interface */
565e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIcoreExtension driCoreExtension = {
566e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    { __DRI_CORE, __DRI_CORE_VERSION },
567f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
568e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyScreen,
569e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetExtensions,
570e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetConfigAttrib,
571e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driIndexConfigAttrib,
572f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
573e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyDrawable,
5746260618b29983fd961718fd6e3961bdd32163cb5Kristian Høgsberg    NULL,
575f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
576e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driCopyContext,
577e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyContext,
578e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driBindContext,
579e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driUnbindContext
580e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
581e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
58239a0e4e7de379a182c1544fa24d5cb2a7687ec72Kristian Høgsberg/** DRI2 interface */
583f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIdri2Extension driDRI2Extension = {
584de9ed5152533c87c21d27b71211a834b4c9767bcIan Romanick    { __DRI_DRI2, 3 },
585f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewScreen,
586f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewDrawable,
587f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewContext,
588a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    dri2GetAPIMask,
5891b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2CreateNewContextForAPI,
5901b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2AllocateBuffer,
5911ab545494a6750527cb8b945c286f23a6524826aIan Romanick    dri2ReleaseBuffer,
592d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    dri2CreateContextAttribs
593f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
594f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
595234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesconst __DRI2configQueryExtension dri2ConfigQueryExtension = {
596234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
597234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryb,
598234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryi,
599234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryf,
600234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes};
601234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
60261d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezvoid
60361d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezdri2InvalidateDrawable(__DRIdrawable *drawable)
60461d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez{
60561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    drawable->dri2.stamp++;
60661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez}
60761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
608c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg/**
609c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * Check that the gl_framebuffer associated with dPriv is the right size.
610c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * Resize the gl_framebuffer if needed.
611c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * It's expected that the dPriv->driverPrivate member points to a
612c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * gl_framebuffer object.
613c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg */
614c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsbergvoid
615c467db4cc765965bd347cf5b91aec39b831273ecKristian HøgsbergdriUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv)
616c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg{
617c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg   struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
618c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg   if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
619c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h);
620c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      /* if the driver needs the hw lock for ResizeBuffers, the drawable
621c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg         might have changed again by now */
622c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      assert(fb->Width == dPriv->w);
623c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      assert(fb->Height == dPriv->h);
624c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg   }
625c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg}
626