dri_util.c revision 0c445bb618479adceb9243098fc20bebac4eecc7
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 */ 2470c445bb618479adceb9243098fc20bebac4eecc7Ian Romanick if (mesa_api != API_OPENGL 2480c445bb618479adceb9243098fc20bebac4eecc7Ian Romanick && mesa_api != 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