dri_util.c revision d9de33c304d875627937cacbfc21f54a406af726
1680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
2680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \file dri_util.c
3680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI utility functions.
4680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
5680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This module acts as glue between GLX and the actual hardware driver.  A DRI
6680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver doesn't really \e have to use any of this - it's optional.  But, some
7680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * useful stuff is done here that otherwise would have to be duplicated in most
8680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drivers.
9680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
10680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Basically, these utility functions take care of some of the dirty details of
11680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * screen initialization, context creation, context binding, DRM setup, etc.
12680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
13680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These functions are compiled into each DRI driver so libGL.so knows nothing
14680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * about them.
15680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
16680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
17680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
187192c37294964b3f6e1551469f161593ec8f851dGeorge Sapountzis#include <xf86drm.h>
197c46033130b1b4d6098647d85c2710367572e079Ian Romanick#include "dri_util.h"
20c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis#include "utils.h"
2145e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes#include "xmlpool.h"
22ae6e112c69cf42fb81ef4ed5bdeb3b280647f141Eric Anholt#include "../glsl/glsl_parser_extras.h"
2345e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
2445e2b51c853471b79004a954ce3092a253b20b77Jesse BarnesPUBLIC const char __dri2ConfigOptions[] =
2545e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   DRI_CONF_BEGIN
2645e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      DRI_CONF_SECTION_PERFORMANCE
2745e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes         DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
2845e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes      DRI_CONF_SECTION_END
2945e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes   DRI_CONF_END;
3045e2b51c853471b79004a954ce3092a253b20b77Jesse Barnes
3145e2b51c853471b79004a954ce3092a253b20b77Jesse Barnesstatic const uint __dri2NConfigOptions = 1;
32680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
33680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
34c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/** \name Screen handling functions                              */
35c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*****************************************************************/
36c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*@{*/
37c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
38c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic void
39c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge SapountzissetupLoaderExtensions(__DRIscreen *psp,
40c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis		      const __DRIextension **extensions)
41c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
42c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    int i;
43c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
44c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    for (i = 0; extensions[i]; i++) {
45c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
46c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	    psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
47c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
48c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	    psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
49c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0)
50c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	    psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
51c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
52c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
53c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
54c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic __DRIscreen *
55c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisdri2CreateNewScreen(int scrn, int fd,
56c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis		    const __DRIextension **extensions,
57c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis		    const __DRIconfig ***driver_configs, void *data)
58c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
59c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    static const __DRIextension *emptyExtensionList[] = { NULL };
60c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    __DRIscreen *psp;
61c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    drmVersionPtr version;
62c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
63c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp = calloc(1, sizeof(*psp));
64c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (!psp)
65c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	return NULL;
66c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
67c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    setupLoaderExtensions(psp, extensions);
68c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
69c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    version = drmGetVersion(fd);
70c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (version) {
71c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	psp->drm_version.major = version->version_major;
72c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	psp->drm_version.minor = version->version_minor;
73c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	psp->drm_version.patch = version->version_patchlevel;
74c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	drmFreeVersion(version);
75c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
76c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
77cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    psp->loaderPrivate = data;
78cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
79c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->extensions = emptyExtensionList;
80c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->fd = fd;
81c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->myNum = scrn;
82c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
83c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    psp->api_mask = (1 << __DRI_API_OPENGL);
84cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
85c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    *driver_configs = driDriverAPI.InitScreen(psp);
86c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (*driver_configs == NULL) {
87c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	free(psp);
88c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	return NULL;
89c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
90c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
91cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions, __dri2NConfigOptions);
92cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2");
93c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
94c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    return psp;
95c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
96c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
97c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/**
98c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * Destroy the per-screen private information.
99c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis *
100c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * \internal
101c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
102c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis * drmClose(), and finally frees \p screenPrivate.
103c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis */
104c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic void driDestroyScreen(__DRIscreen *psp)
105c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
106c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    if (psp) {
107c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	/* No interaction with the X-server is possible at this point.  This
108c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	 * routine is called after XCloseDisplay, so there is no protocol
109c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	 * stream open to the X-server anymore.
110c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	 */
111c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
112c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis       _mesa_destroy_shader_compiler();
113c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
114cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	driDriverAPI.DestroyScreen(psp);
115c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
116c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	driDestroyOptionCache(&psp->optionCache);
117c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	driDestroyOptionInfo(&psp->optionInfo);
118c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
119c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis	free(psp);
120c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    }
121c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
122c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
123c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzisstatic const __DRIextension **driGetExtensions(__DRIscreen *psp)
124c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis{
125c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis    return psp->extensions;
126c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis}
127c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
128c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*@}*/
129c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
130c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis
131c98d15c9f5cf7e8d2a8f8e9e56ed08786b91c86bGeorge Sapountzis/*****************************************************************/
1329292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/** \name Context handling functions                             */
1339292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*****************************************************************/
1349292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*@{*/
1359292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
1369292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic __DRIcontext *
137d9de33c304d875627937cacbfc21f54a406af726Ian Romanickdri2CreateContextAttribs(__DRIscreen *screen, int api,
138d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 const __DRIconfig *config,
139d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 __DRIcontext *shared,
140d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 unsigned num_attribs,
141d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 const uint32_t *attribs,
142d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 unsigned *error,
143d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			 void *data)
1449292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
1459292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    __DRIcontext *context;
1469292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
1479292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
1489292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    gl_api mesa_api;
149d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    unsigned major_version = 1;
150d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    unsigned minor_version = 0;
151d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    uint32_t flags = 0;
152d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
153d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    assert((num_attribs == 0) || (attribs != NULL));
1549292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
155d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    if (!(screen->api_mask & (1 << api))) {
156d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	*error = __DRI_CTX_ERROR_BAD_API;
1579292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	return NULL;
158d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
1599292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
1609292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    switch (api) {
1619292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    case __DRI_API_OPENGL:
162d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	mesa_api = API_OPENGL;
163d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	break;
1649292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    case __DRI_API_GLES:
165d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	mesa_api = API_OPENGLES;
166d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	break;
1679292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    case __DRI_API_GLES2:
168d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	mesa_api = API_OPENGLES2;
169d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	break;
170d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    case __DRI_API_OPENGL_CORE:
1719292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    default:
172d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	*error = __DRI_CTX_ERROR_BAD_API;
173d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	return NULL;
174d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
175d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
176d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    if (mesa_api != API_OPENGL && num_attribs != 0) {
177d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	*error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
178d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	assert(!"Should not get here.");
179d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	return NULL;
180d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
181d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
182d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    for (unsigned i = 0; i < num_attribs; i++) {
183d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	switch (attribs[i * 2]) {
184d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	case __DRI_CTX_ATTRIB_MAJOR_VERSION:
185d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    major_version = attribs[i * 2 + 1];
186d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    break;
187d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	case __DRI_CTX_ATTRIB_MINOR_VERSION:
188d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    minor_version = attribs[i * 2 + 1];
189d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    break;
190d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	case __DRI_CTX_ATTRIB_FLAGS:
191d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    flags = attribs[i * 2 + 1];
192d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    break;
193d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	default:
194d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    /* We can't create a context that satisfies the requirements of an
195d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	     * attribute that we don't understand.  Return failure.
196d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	     */
197d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	    return NULL;
198d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	}
199d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
200d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
201d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    /* There are no forward-compatible contexts before OpenGL 3.0.  The
202d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * GLX_ARB_create_context spec says:
203d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *
204d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *     "Forward-compatible contexts are defined only for OpenGL versions
205d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *     3.0 and later."
206d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *
207d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * Moreover, Mesa can't fulfill the requirements of a forward-looking
208d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * context.  Return failure if a forward-looking context is requested.
209d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     *
210d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     * In Mesa, a debug context is the same as a regular context.
211d9de33c304d875627937cacbfc21f54a406af726Ian Romanick     */
212d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    if (major_version >= 3) {
213d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	if ((flags & ~__DRI_CTX_FLAG_DEBUG) != 0)
2149292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	    return NULL;
2159292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    }
2169292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2179292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    context = malloc(sizeof *context);
218d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    if (!context) {
219d9de33c304d875627937cacbfc21f54a406af726Ian Romanick	*error = __DRI_CTX_ERROR_NO_MEMORY;
2209292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	return NULL;
221d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    }
2229292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
223cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    context->loaderPrivate = data;
224cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
2259292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    context->driScreenPriv = screen;
2269292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    context->driDrawablePriv = NULL;
227cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    context->driReadablePriv = NULL;
2289292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
229cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    if (!driDriverAPI.CreateContext(mesa_api, modes, context, shareCtx) ) {
2309292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis        free(context);
2319292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis        return NULL;
2329292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    }
2339292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
234d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    *error = __DRI_CTX_ERROR_SUCCESS;
2359292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    return context;
2369292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
2379292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
238d9de33c304d875627937cacbfc21f54a406af726Ian Romanickstatic __DRIcontext *
239d9de33c304d875627937cacbfc21f54a406af726Ian Romanickdri2CreateNewContextForAPI(__DRIscreen *screen, int api,
240d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			   const __DRIconfig *config,
241d9de33c304d875627937cacbfc21f54a406af726Ian Romanick			   __DRIcontext *shared, void *data)
242d9de33c304d875627937cacbfc21f54a406af726Ian Romanick{
243d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    unsigned error;
244d9de33c304d875627937cacbfc21f54a406af726Ian Romanick
245d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL,
246d9de33c304d875627937cacbfc21f54a406af726Ian Romanick				    data, &error);
247d9de33c304d875627937cacbfc21f54a406af726Ian Romanick}
2489292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2499292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic __DRIcontext *
2509292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisdri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
2519292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis		      __DRIcontext *shared, void *data)
2529292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
253cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
254cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis				      config, shared, data);
2559292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
2569292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2579292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/**
2589292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * Destroy the per-context private information.
2599292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis *
2609292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * \internal
2619292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
2629292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis * drmDestroyContext(), and finally frees \p contextPrivate.
2639292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis */
2649292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic void
2659292ab7190b7f5805e1670be63022716035d067eGeorge SapountzisdriDestroyContext(__DRIcontext *pcp)
2669292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
2679292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    if (pcp) {
2689292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	driDriverAPI.DestroyContext(pcp);
2699292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis	free(pcp);
2709292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    }
2719292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
2729292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2739292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzisstatic int
2749292ab7190b7f5805e1670be63022716035d067eGeorge SapountzisdriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
2759292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis{
2769292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    (void) dest;
2779292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    (void) src;
2789292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    (void) mask;
2799292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis    return GL_FALSE;
2809292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis}
2819292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2829292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*@}*/
2839292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2849292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis
2859292ab7190b7f5805e1670be63022716035d067eGeorge Sapountzis/*****************************************************************/
286680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions                          */
287680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
288680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
289680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
2902314021d603afa40321fb7b50881bc85d406c921George Sapountzisstatic void dri_get_drawable(__DRIdrawable *pdp);
2912314021d603afa40321fb7b50881bc85d406c921George Sapountzisstatic void dri_put_drawable(__DRIdrawable *pdp);
2922314021d603afa40321fb7b50881bc85d406c921George Sapountzis
2932314021d603afa40321fb7b50881bc85d406c921George Sapountzis/**
2942314021d603afa40321fb7b50881bc85d406c921George Sapountzis * This function takes both a read buffer and a draw buffer.  This is needed
2952314021d603afa40321fb7b50881bc85d406c921George Sapountzis * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
2962314021d603afa40321fb7b50881bc85d406c921George Sapountzis * function.
2972314021d603afa40321fb7b50881bc85d406c921George Sapountzis */
2982314021d603afa40321fb7b50881bc85d406c921George Sapountzisstatic int driBindContext(__DRIcontext *pcp,
2992314021d603afa40321fb7b50881bc85d406c921George Sapountzis			  __DRIdrawable *pdp,
3002314021d603afa40321fb7b50881bc85d406c921George Sapountzis			  __DRIdrawable *prp)
3012314021d603afa40321fb7b50881bc85d406c921George Sapountzis{
3022314021d603afa40321fb7b50881bc85d406c921George Sapountzis    /*
3032314021d603afa40321fb7b50881bc85d406c921George Sapountzis    ** Assume error checking is done properly in glXMakeCurrent before
3042314021d603afa40321fb7b50881bc85d406c921George Sapountzis    ** calling driUnbindContext.
3052314021d603afa40321fb7b50881bc85d406c921George Sapountzis    */
3062314021d603afa40321fb7b50881bc85d406c921George Sapountzis
3072314021d603afa40321fb7b50881bc85d406c921George Sapountzis    if (!pcp)
3082314021d603afa40321fb7b50881bc85d406c921George Sapountzis	return GL_FALSE;
3092314021d603afa40321fb7b50881bc85d406c921George Sapountzis
3102314021d603afa40321fb7b50881bc85d406c921George Sapountzis    /* Bind the drawable to the context */
3112314021d603afa40321fb7b50881bc85d406c921George Sapountzis    pcp->driDrawablePriv = pdp;
3122314021d603afa40321fb7b50881bc85d406c921George Sapountzis    pcp->driReadablePriv = prp;
3132314021d603afa40321fb7b50881bc85d406c921George Sapountzis    if (pdp) {
3142314021d603afa40321fb7b50881bc85d406c921George Sapountzis	pdp->driContextPriv = pcp;
3152314021d603afa40321fb7b50881bc85d406c921George Sapountzis	dri_get_drawable(pdp);
3162314021d603afa40321fb7b50881bc85d406c921George Sapountzis    }
3172314021d603afa40321fb7b50881bc85d406c921George Sapountzis    if (prp && pdp != prp) {
3182314021d603afa40321fb7b50881bc85d406c921George Sapountzis	dri_get_drawable(prp);
3192314021d603afa40321fb7b50881bc85d406c921George Sapountzis    }
3202314021d603afa40321fb7b50881bc85d406c921George Sapountzis
3212314021d603afa40321fb7b50881bc85d406c921George Sapountzis    return driDriverAPI.MakeCurrent(pcp, pdp, prp);
3222314021d603afa40321fb7b50881bc85d406c921George Sapountzis}
3232314021d603afa40321fb7b50881bc85d406c921George Sapountzis
324680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
325680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context.
326680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
327aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg * \param scrn the screen.
328680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context.
329680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
330680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
331680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
332680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
333680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements
334d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * __DRIdrawableRec::refcount which must be non-zero for a successful
335680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return.
336680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
337680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters
338680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL.
339680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
340e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driUnbindContext(__DRIcontext *pcp)
341680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
342418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *pdp;
343418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *prp;
344680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
345680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
346680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
347c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    ** calling driUnbindContext.
348680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
349680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
350e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (pcp == NULL)
351cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	return GL_FALSE;
352680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
353418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pdp = pcp->driDrawablePriv;
354418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    prp = pcp->driReadablePriv;
355680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
356418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* already unbound */
357418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (!pdp && !prp)
358cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	return GL_TRUE;
359cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
360875a757ddd103722cfe9a2b21035024aa5a23d32George Sapountzis    driDriverAPI.UnbindContext(pcp);
361680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
362cab77711b3e8d398393677bcefcd413f50503a64Vinson Lee    assert(pdp);
363418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (pdp->refcount == 0) {
364418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	/* ERROR!!! */
365418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	return GL_FALSE;
366418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
367418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
368418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    dri_put_drawable(pdp);
369418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
370418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (prp != pdp) {
371cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	if (prp->refcount == 0) {
372418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    /* ERROR!!! */
373418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    return GL_FALSE;
374418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	}
375418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
376cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	dri_put_drawable(prp);
377418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
378418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
379418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* XXX this is disabled so that if we call SwapBuffers on an unbound
380418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * window we can determine the last context bound to the window and
381418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * use that context's lock. (BrianP, 2-Dec-2000)
382418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     */
383cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pcp->driDrawablePriv = NULL;
384cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pcp->driReadablePriv = NULL;
385418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
386680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
387680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
388680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3892314021d603afa40321fb7b50881bc85d406c921George Sapountzis/*@}*/
390680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
391680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3922fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzisstatic void dri_get_drawable(__DRIdrawable *pdp)
3932fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis{
3942fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    pdp->refcount++;
3952fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis}
3962fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
3972fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzisstatic void dri_put_drawable(__DRIdrawable *pdp)
3982fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis{
3992fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    if (pdp) {
4002fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	pdp->refcount--;
4012fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	if (pdp->refcount)
4022fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	    return;
4032fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
404cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis	driDriverAPI.DestroyBuffer(pdp);
4052fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis	free(pdp);
4062fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    }
4072fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis}
4082fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
409e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
410f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsbergdri2CreateNewDrawable(__DRIscreen *screen,
411f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg		      const __DRIconfig *config,
412cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis		      void *data)
413680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
414f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    __DRIdrawable *pdraw;
415680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
416f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw = malloc(sizeof *pdraw);
417f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    if (!pdraw)
418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
419680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
420cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pdraw->loaderPrivate = data;
421cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
422cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pdraw->driScreenPriv = screen;
423f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->driContextPriv = NULL;
424cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    pdraw->refcount = 0;
425f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->lastStamp = 0;
426f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->w = 0;
427f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg    pdraw->h = 0;
428f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg
429cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    dri_get_drawable(pdraw);
430cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis
431cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    if (!driDriverAPI.CreateBuffer(screen, pdraw, &config->modes, GL_FALSE)) {
432f5ba7662bdaf7f8d62cbc1c0c0a59dabb242e78bKristian Høgsberg       free(pdraw);
433680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       return NULL;
434680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
435680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
436e9beaf65fdaf82a7845cbe176f353ddb6b8466c7Kristian Høgsberg    pdraw->dri2.stamp = pdraw->lastStamp + 1;
43761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
438e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdraw;
439680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
440680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4412fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzisstatic void
4422fbba6bb906a4389de64cc6e961b531d8cd5c495George SapountzisdriDestroyDrawable(__DRIdrawable *pdp)
4432fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis{
4442fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis    dri_put_drawable(pdp);
4452fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis}
4462fbba6bb906a4389de64cc6e961b531d8cd5c495George Sapountzis
4471b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic __DRIbuffer *
4481b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2AllocateBuffer(__DRIscreen *screen,
4491b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   unsigned int attachment, unsigned int format,
4501b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke		   int width, int height)
4511b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
452875a757ddd103722cfe9a2b21035024aa5a23d32George Sapountzis    return driDriverAPI.AllocateBuffer(screen, attachment, format,
453875a757ddd103722cfe9a2b21035024aa5a23d32George Sapountzis				       width, height);
4541b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
4551b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
4561b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkestatic void
4571b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzkedri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
4581b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke{
459cd86a5d2f862f183f85ef8c7d51f69e028d04447George Sapountzis    driDriverAPI.ReleaseBuffer(screen, buffer);
4601b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke}
4611b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
4621b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke
463234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
464234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val)
465234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
466234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
467234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
468234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
469234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   *val = driQueryOptionb(&screen->optionCache, var);
470234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
471234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   return 0;
472234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
473234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
474234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
475234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val)
476234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
477234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
478234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes       !driCheckOption(&screen->optionCache, var, DRI_ENUM))
479234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
480234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
481234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptioni(&screen->optionCache, var);
482234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
483234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
484234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
485234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
486234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesstatic int
487234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesdri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
488234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes{
489234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
490234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes      return -1;
491234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
492234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    *val = driQueryOptionf(&screen->optionCache, var);
493234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
494234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes    return 0;
495234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes}
496234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
497a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic unsigned int
498a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2GetAPIMask(__DRIscreen *screen)
499a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
500a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return screen->api_mask;
501a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
502a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
503e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
504f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Core interface */
505e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIcoreExtension driCoreExtension = {
506e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    { __DRI_CORE, __DRI_CORE_VERSION },
507f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
508e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyScreen,
509e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetExtensions,
510e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetConfigAttrib,
511e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driIndexConfigAttrib,
512f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
513e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyDrawable,
5146260618b29983fd961718fd6e3961bdd32163cb5Kristian Høgsberg    NULL,
515f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
516e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driCopyContext,
517e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyContext,
518e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driBindContext,
519e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driUnbindContext
520e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
521e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
52239a0e4e7de379a182c1544fa24d5cb2a7687ec72Kristian Høgsberg/** DRI2 interface */
523f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIdri2Extension driDRI2Extension = {
5241ab545494a6750527cb8b945c286f23a6524826aIan Romanick    /* Force the version to 2 because the underlying drivers don't (can't!)
5251ab545494a6750527cb8b945c286f23a6524826aIan Romanick     * support the extra requirements of CreateContextAttribs.
5261ab545494a6750527cb8b945c286f23a6524826aIan Romanick     */
5271ab545494a6750527cb8b945c286f23a6524826aIan Romanick    { __DRI_DRI2, 2 },
528f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewScreen,
529f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewDrawable,
530f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewContext,
531a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    dri2GetAPIMask,
5321b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2CreateNewContextForAPI,
5331b8ef9416bf3a4d2d47fcf9935063af57da2975dBenjamin Franzke    dri2AllocateBuffer,
5341ab545494a6750527cb8b945c286f23a6524826aIan Romanick    dri2ReleaseBuffer,
535d9de33c304d875627937cacbfc21f54a406af726Ian Romanick    dri2CreateContextAttribs
536f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
537f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
538234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnesconst __DRI2configQueryExtension dri2ConfigQueryExtension = {
539234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
540234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryb,
541234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryi,
542234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes   dri2ConfigQueryf,
543234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes};
544234286c0f8b7d30ed49223c648d4c73c1a517ab3Jesse Barnes
54561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezvoid
54661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezdri2InvalidateDrawable(__DRIdrawable *drawable)
54761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez{
54861d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    drawable->dri2.stamp++;
54961d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez}
55061d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
551c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg/**
552c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * Check that the gl_framebuffer associated with dPriv is the right size.
553c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * Resize the gl_framebuffer if needed.
554c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * It's expected that the dPriv->driverPrivate member points to a
555c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg * gl_framebuffer object.
556c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg */
557c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsbergvoid
558c467db4cc765965bd347cf5b91aec39b831273ecKristian HøgsbergdriUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv)
559c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg{
560c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg   struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
561c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg   if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
562c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h);
563c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      /* if the driver needs the hw lock for ResizeBuffers, the drawable
564c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg         might have changed again by now */
565c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      assert(fb->Width == dPriv->w);
566c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg      assert(fb->Height == dPriv->h);
567c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg   }
568c467db4cc765965bd347cf5b91aec39b831273ecKristian Høgsberg}
569