2 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
28 * DRISW utility functions, i.e. dri_util.c stripped from drm-specific bits.
40 setupLoaderExtensions(__DRIscreen
*psp
,
41 const __DRIextension
**extensions
)
45 for (i
= 0; extensions
[i
]; i
++) {
46 if (strcmp(extensions
[i
]->name
, __DRI_SWRAST_LOADER
) == 0)
47 psp
->swrast_loader
= (__DRIswrastLoaderExtension
*) extensions
[i
];
52 driCreateNewScreen(int scrn
, const __DRIextension
**extensions
,
53 const __DRIconfig
***driver_configs
, void *data
)
55 static const __DRIextension
*emptyExtensionList
[] = { NULL
};
58 psp
= CALLOC_STRUCT(__DRIscreenRec
);
62 setupLoaderExtensions(psp
, extensions
);
64 psp
->loaderPrivate
= data
;
66 psp
->extensions
= emptyExtensionList
;
70 *driver_configs
= driDriverAPI
.InitScreen(psp
);
71 if (*driver_configs
== NULL
) {
79 static void driDestroyScreen(__DRIscreen
*psp
)
82 driDriverAPI
.DestroyScreen(psp
);
87 static const __DRIextension
**driGetExtensions(__DRIscreen
*psp
)
89 return psp
->extensions
;
98 driCreateContextAttribs(__DRIscreen
*screen
, int api
,
99 const __DRIconfig
*config
,
100 __DRIcontext
*shared
,
101 unsigned num_attribs
,
102 const uint32_t *attribs
,
107 const struct gl_config
*modes
= (config
!= NULL
) ? &config
->modes
: NULL
;
108 void * const shareCtx
= (shared
!= NULL
) ? shared
->driverPrivate
: NULL
;
110 unsigned major_version
= 1;
111 unsigned minor_version
= 0;
114 /* Either num_attribs is zero and attribs is NULL, or num_attribs is not
115 * zero and attribs is not NULL.
117 assert((num_attribs
== 0) == (attribs
== NULL
));
120 case __DRI_API_OPENGL
:
121 mesa_api
= API_OPENGL_COMPAT
;
124 mesa_api
= API_OPENGLES
;
126 case __DRI_API_GLES2
:
127 case __DRI_API_GLES3
:
128 mesa_api
= API_OPENGLES2
;
130 case __DRI_API_OPENGL_CORE
:
131 mesa_api
= API_OPENGL_CORE
;
134 *error
= __DRI_CTX_ERROR_BAD_API
;
138 for (unsigned i
= 0; i
< num_attribs
; i
++) {
139 switch (attribs
[i
* 2]) {
140 case __DRI_CTX_ATTRIB_MAJOR_VERSION
:
141 major_version
= attribs
[i
* 2 + 1];
143 case __DRI_CTX_ATTRIB_MINOR_VERSION
:
144 minor_version
= attribs
[i
* 2 + 1];
146 case __DRI_CTX_ATTRIB_FLAGS
:
147 flags
= attribs
[i
* 2 + 1];
150 /* We can't create a context that satisfies the requirements of an
151 * attribute that we don't understand. Return failure.
157 /* Mesa does not support the GL_ARB_compatibilty extension or the
158 * compatibility profile. This means that we treat a API_OPENGL_COMPAT 3.1 as
159 * API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+.
161 if (mesa_api
== API_OPENGL_COMPAT
&& major_version
== 3 && minor_version
== 1)
162 mesa_api
= API_OPENGL_CORE
;
164 if (mesa_api
== API_OPENGL_COMPAT
165 && ((major_version
> 3)
166 || (major_version
== 3 && minor_version
>= 2))) {
167 *error
= __DRI_CTX_ERROR_BAD_API
;
170 /* There are no forward-compatible contexts before OpenGL 3.0. The
171 * GLX_ARB_create_context spec says:
173 * "Forward-compatible contexts are defined only for OpenGL versions
176 * Moreover, Mesa can't fulfill the requirements of a forward-looking
177 * context. Return failure if a forward-looking context is requested.
179 * In Mesa, a debug context is the same as a regular context.
181 if (major_version
>= 3) {
182 if ((flags
& ~__DRI_CTX_FLAG_DEBUG
) != 0)
186 pcp
= CALLOC_STRUCT(__DRIcontextRec
);
190 pcp
->loaderPrivate
= data
;
192 pcp
->driScreenPriv
= screen
;
193 pcp
->driDrawablePriv
= NULL
;
194 pcp
->driReadablePriv
= NULL
;
196 if (!driDriverAPI
.CreateContext(mesa_api
, modes
, pcp
,
197 major_version
, minor_version
,
198 flags
, error
, shareCtx
)) {
206 static __DRIcontext
*
207 driCreateNewContextForAPI(__DRIscreen
*psp
, int api
,
208 const __DRIconfig
*config
,
209 __DRIcontext
*shared
, void *data
)
213 return driCreateContextAttribs(psp
, api
, config
, shared
, 0, NULL
,
217 static __DRIcontext
*
218 driCreateNewContext(__DRIscreen
*psp
, const __DRIconfig
*config
,
219 __DRIcontext
*shared
, void *data
)
221 return driCreateNewContextForAPI(psp
, __DRI_API_OPENGL
,
222 config
, shared
, data
);
226 driDestroyContext(__DRIcontext
*pcp
)
229 driDriverAPI
.DestroyContext(pcp
);
235 driCopyContext(__DRIcontext
*dst
, __DRIcontext
*src
, unsigned long mask
)
240 static void dri_get_drawable(__DRIdrawable
*pdp
);
241 static void dri_put_drawable(__DRIdrawable
*pdp
);
243 static int driBindContext(__DRIcontext
*pcp
,
247 /* Bind the drawable to the context */
249 pcp
->driDrawablePriv
= pdp
;
250 pcp
->driReadablePriv
= prp
;
252 pdp
->driContextPriv
= pcp
;
253 dri_get_drawable(pdp
);
255 if (prp
&& pdp
!= prp
) {
256 dri_get_drawable(prp
);
260 return driDriverAPI
.MakeCurrent(pcp
, pdp
, prp
);
263 static int driUnbindContext(__DRIcontext
*pcp
)
271 pdp
= pcp
->driDrawablePriv
;
272 prp
= pcp
->driReadablePriv
;
274 /* already unbound */
278 driDriverAPI
.UnbindContext(pcp
);
280 dri_put_drawable(pdp
);
283 dri_put_drawable(prp
);
286 pcp
->driDrawablePriv
= NULL
;
287 pcp
->driReadablePriv
= NULL
;
297 static void dri_get_drawable(__DRIdrawable
*pdp
)
302 static void dri_put_drawable(__DRIdrawable
*pdp
)
309 driDriverAPI
.DestroyBuffer(pdp
);
314 static __DRIdrawable
*
315 driCreateNewDrawable(__DRIscreen
*psp
,
316 const __DRIconfig
*config
, void *data
)
320 pdp
= CALLOC_STRUCT(__DRIdrawableRec
);
324 pdp
->loaderPrivate
= data
;
326 pdp
->driScreenPriv
= psp
;
327 pdp
->driContextPriv
= NULL
;
329 dri_get_drawable(pdp
);
331 if (!driDriverAPI
.CreateBuffer(psp
, pdp
, &config
->modes
, GL_FALSE
)) {
336 pdp
->lastStamp
= 1; /* const */
342 driDestroyDrawable(__DRIdrawable
*pdp
)
344 dri_put_drawable(pdp
);
347 static void driSwapBuffers(__DRIdrawable
*pdp
)
349 driDriverAPI
.SwapBuffers(pdp
);
352 const __DRIcoreExtension driCoreExtension
= {
353 { __DRI_CORE
, __DRI_CORE_VERSION
},
354 NULL
, /* driCreateNewScreen */
358 driIndexConfigAttrib
,
359 NULL
, /* driCreateNewDrawable */
369 const __DRIswrastExtension driSWRastExtension
= {
370 { __DRI_SWRAST
, __DRI_SWRAST_VERSION
},
372 driCreateNewDrawable
,
373 driCreateNewContextForAPI
,
374 driCreateContextAttribs