2 * (C) Copyright IBM Corporation 2002, 2004
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * DRI utility functions.
29 * This module acts as glue between GLX and the actual hardware driver. A DRI
30 * driver doesn't really \e have to use any of this - it's optional. But, some
31 * useful stuff is done here that otherwise would have to be duplicated in most
34 * Basically, these utility functions take care of some of the dirty details of
35 * screen initialization, context creation, context binding, DRM setup, etc.
37 * These functions are compiled into each DRI driver so libGL.so knows nothing
45 #include "util/u_endian.h"
46 #include "util/xmlpool.h"
47 #include "main/mtypes.h"
48 #include "main/framebuffer.h"
49 #include "main/version.h"
50 #include "main/debug_output.h"
51 #include "main/errors.h"
52 #include "main/macros.h"
54 const char __dri2ConfigOptions
[] =
56 DRI_CONF_SECTION_PERFORMANCE
57 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1
)
61 /*****************************************************************/
62 /** \name Screen handling functions */
63 /*****************************************************************/
67 setupLoaderExtensions(__DRIscreen
*psp
,
68 const __DRIextension
**extensions
)
72 for (i
= 0; extensions
[i
]; i
++) {
73 if (strcmp(extensions
[i
]->name
, __DRI_DRI2_LOADER
) == 0)
74 psp
->dri2
.loader
= (__DRIdri2LoaderExtension
*) extensions
[i
];
75 if (strcmp(extensions
[i
]->name
, __DRI_IMAGE_LOOKUP
) == 0)
76 psp
->dri2
.image
= (__DRIimageLookupExtension
*) extensions
[i
];
77 if (strcmp(extensions
[i
]->name
, __DRI_USE_INVALIDATE
) == 0)
78 psp
->dri2
.useInvalidate
= (__DRIuseInvalidateExtension
*) extensions
[i
];
79 if (strcmp(extensions
[i
]->name
, __DRI_BACKGROUND_CALLABLE
) == 0)
80 psp
->dri2
.backgroundCallable
= (__DRIbackgroundCallableExtension
*) extensions
[i
];
81 if (strcmp(extensions
[i
]->name
, __DRI_SWRAST_LOADER
) == 0)
82 psp
->swrast_loader
= (__DRIswrastLoaderExtension
*) extensions
[i
];
83 if (strcmp(extensions
[i
]->name
, __DRI_IMAGE_LOADER
) == 0)
84 psp
->image
.loader
= (__DRIimageLoaderExtension
*) extensions
[i
];
85 if (strcmp(extensions
[i
]->name
, __DRI_MUTABLE_RENDER_BUFFER_LOADER
) == 0)
86 psp
->mutableRenderBuffer
.loader
= (__DRImutableRenderBufferLoaderExtension
*) extensions
[i
];
91 * This pointer determines which driver API we'll use in the case of the
92 * loader not passing us an explicit driver extensions list (that would,
93 * itself, contain a pointer to a driver API.)
95 * A driver's driDriverGetExtensions_drivername() can update this pointer to
96 * what it's returning, and a loader that is ignorant of createNewScreen2()
97 * will get the correct driver screen created, as long as no other
98 * driDriverGetExtensions() happened in between the first one and the
101 * This allows the X Server to not require the significant dri_interface.h
102 * updates for doing createNewScreen2(), which would discourage backporting of
103 * the X Server patches to support the new loader interface.
105 const struct __DriverAPIRec
*globalDriverAPI
= &driDriverAPI
;
108 * This is the first entrypoint in the driver called by the DRI driver loader
109 * after dlopen()ing it.
111 * It's used to create global state for the driver across contexts on the same
115 driCreateNewScreen2(int scrn
, int fd
,
116 const __DRIextension
**extensions
,
117 const __DRIextension
**driver_extensions
,
118 const __DRIconfig
***driver_configs
, void *data
)
120 static const __DRIextension
*emptyExtensionList
[] = { NULL
};
123 psp
= calloc(1, sizeof(*psp
));
127 /* By default, use the global driDriverAPI symbol (non-megadrivers). */
128 psp
->driver
= globalDriverAPI
;
130 /* If the driver exposes its vtable through its extensions list
131 * (megadrivers), use that instead.
133 if (driver_extensions
) {
134 for (int i
= 0; driver_extensions
[i
]; i
++) {
135 if (strcmp(driver_extensions
[i
]->name
, __DRI_DRIVER_VTABLE
) == 0) {
137 ((__DRIDriverVtableExtension
*)driver_extensions
[i
])->vtable
;
142 setupLoaderExtensions(psp
, extensions
);
144 psp
->loaderPrivate
= data
;
146 psp
->extensions
= emptyExtensionList
;
150 /* Option parsing before ->InitScreen(), as some options apply there. */
151 driParseOptionInfo(&psp
->optionInfo
, __dri2ConfigOptions
);
152 driParseConfigFiles(&psp
->optionCache
, &psp
->optionInfo
, psp
->myNum
,
153 "dri2", NULL
, NULL
, 0);
155 *driver_configs
= psp
->driver
->InitScreen(psp
);
156 if (*driver_configs
== NULL
) {
161 struct gl_constants consts
= { 0 };
166 if (_mesa_override_gl_version_contextless(&consts
, &api
, &version
))
167 psp
->max_gl_es2_version
= version
;
169 api
= API_OPENGL_COMPAT
;
170 if (_mesa_override_gl_version_contextless(&consts
, &api
, &version
)) {
171 psp
->max_gl_core_version
= version
;
172 if (api
== API_OPENGL_COMPAT
)
173 psp
->max_gl_compat_version
= version
;
177 if (psp
->max_gl_compat_version
> 0)
178 psp
->api_mask
|= (1 << __DRI_API_OPENGL
);
179 if (psp
->max_gl_core_version
> 0)
180 psp
->api_mask
|= (1 << __DRI_API_OPENGL_CORE
);
181 if (psp
->max_gl_es1_version
> 0)
182 psp
->api_mask
|= (1 << __DRI_API_GLES
);
183 if (psp
->max_gl_es2_version
> 0)
184 psp
->api_mask
|= (1 << __DRI_API_GLES2
);
185 if (psp
->max_gl_es2_version
>= 30)
186 psp
->api_mask
|= (1 << __DRI_API_GLES3
);
192 dri2CreateNewScreen(int scrn
, int fd
,
193 const __DRIextension
**extensions
,
194 const __DRIconfig
***driver_configs
, void *data
)
196 return driCreateNewScreen2(scrn
, fd
, extensions
, NULL
,
197 driver_configs
, data
);
200 /** swrast driver createNewScreen entrypoint. */
202 driSWRastCreateNewScreen(int scrn
, const __DRIextension
**extensions
,
203 const __DRIconfig
***driver_configs
, void *data
)
205 return driCreateNewScreen2(scrn
, -1, extensions
, NULL
,
206 driver_configs
, data
);
210 driSWRastCreateNewScreen2(int scrn
, const __DRIextension
**extensions
,
211 const __DRIextension
**driver_extensions
,
212 const __DRIconfig
***driver_configs
, void *data
)
214 return driCreateNewScreen2(scrn
, -1, extensions
, driver_extensions
,
215 driver_configs
, data
);
219 * Destroy the per-screen private information.
222 * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
223 * drmClose(), and finally frees \p screenPrivate.
225 static void driDestroyScreen(__DRIscreen
*psp
)
228 /* No interaction with the X-server is possible at this point. This
229 * routine is called after XCloseDisplay, so there is no protocol
230 * stream open to the X-server anymore.
233 psp
->driver
->DestroyScreen(psp
);
235 driDestroyOptionCache(&psp
->optionCache
);
236 driDestroyOptionInfo(&psp
->optionInfo
);
242 static const __DRIextension
**driGetExtensions(__DRIscreen
*psp
)
244 return psp
->extensions
;
251 validate_context_version(__DRIscreen
*screen
,
253 unsigned major_version
,
254 unsigned minor_version
,
255 unsigned *dri_ctx_error
)
257 unsigned req_version
= 10 * major_version
+ minor_version
;
258 unsigned max_version
= 0;
261 case API_OPENGL_COMPAT
:
262 max_version
= screen
->max_gl_compat_version
;
264 case API_OPENGL_CORE
:
265 max_version
= screen
->max_gl_core_version
;
268 max_version
= screen
->max_gl_es1_version
;
271 max_version
= screen
->max_gl_es2_version
;
278 if (max_version
== 0) {
279 *dri_ctx_error
= __DRI_CTX_ERROR_BAD_API
;
281 } else if (req_version
> max_version
) {
282 *dri_ctx_error
= __DRI_CTX_ERROR_BAD_VERSION
;
289 /*****************************************************************/
290 /** \name Context handling functions */
291 /*****************************************************************/
294 static __DRIcontext
*
295 driCreateContextAttribs(__DRIscreen
*screen
, int api
,
296 const __DRIconfig
*config
,
297 __DRIcontext
*shared
,
298 unsigned num_attribs
,
299 const uint32_t *attribs
,
303 __DRIcontext
*context
;
304 const struct gl_config
*modes
= (config
!= NULL
) ? &config
->modes
: NULL
;
305 void *shareCtx
= (shared
!= NULL
) ? shared
->driverPrivate
: NULL
;
307 struct __DriverContextConfig ctx_config
;
309 ctx_config
.major_version
= 1;
310 ctx_config
.minor_version
= 0;
311 ctx_config
.flags
= 0;
312 ctx_config
.attribute_mask
= 0;
313 ctx_config
.priority
= __DRI_CTX_PRIORITY_MEDIUM
;
315 assert((num_attribs
== 0) || (attribs
!= NULL
));
317 if (!(screen
->api_mask
& (1 << api
))) {
318 *error
= __DRI_CTX_ERROR_BAD_API
;
323 case __DRI_API_OPENGL
:
324 mesa_api
= API_OPENGL_COMPAT
;
327 mesa_api
= API_OPENGLES
;
329 case __DRI_API_GLES2
:
330 case __DRI_API_GLES3
:
331 mesa_api
= API_OPENGLES2
;
333 case __DRI_API_OPENGL_CORE
:
334 mesa_api
= API_OPENGL_CORE
;
337 *error
= __DRI_CTX_ERROR_BAD_API
;
341 for (unsigned i
= 0; i
< num_attribs
; i
++) {
342 switch (attribs
[i
* 2]) {
343 case __DRI_CTX_ATTRIB_MAJOR_VERSION
:
344 ctx_config
.major_version
= attribs
[i
* 2 + 1];
346 case __DRI_CTX_ATTRIB_MINOR_VERSION
:
347 ctx_config
.minor_version
= attribs
[i
* 2 + 1];
349 case __DRI_CTX_ATTRIB_FLAGS
:
350 ctx_config
.flags
= attribs
[i
* 2 + 1];
352 case __DRI_CTX_ATTRIB_RESET_STRATEGY
:
353 if (attribs
[i
* 2 + 1] != __DRI_CTX_RESET_NO_NOTIFICATION
) {
354 ctx_config
.attribute_mask
|=
355 __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY
;
356 ctx_config
.reset_strategy
= attribs
[i
* 2 + 1];
358 ctx_config
.attribute_mask
&=
359 ~__DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY
;
362 case __DRI_CTX_ATTRIB_PRIORITY
:
363 ctx_config
.attribute_mask
|= __DRIVER_CONTEXT_ATTRIB_PRIORITY
;
364 ctx_config
.priority
= attribs
[i
* 2 + 1];
366 case __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR
:
367 if (attribs
[i
* 2 + 1] != __DRI_CTX_RELEASE_BEHAVIOR_FLUSH
) {
368 ctx_config
.attribute_mask
|=
369 __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR
;
370 ctx_config
.release_behavior
= attribs
[i
* 2 + 1];
372 ctx_config
.attribute_mask
&=
373 ~__DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR
;
377 /* We can't create a context that satisfies the requirements of an
378 * attribute that we don't understand. Return failure.
380 assert(!"Should not get here.");
381 *error
= __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE
;
386 /* The specific Mesa driver may not support the GL_ARB_compatibilty
387 * extension or the compatibility profile. In that case, we treat an
388 * API_OPENGL_COMPAT 3.1 as API_OPENGL_CORE. We reject API_OPENGL_COMPAT
391 if (mesa_api
== API_OPENGL_COMPAT
&&
392 ctx_config
.major_version
== 3 && ctx_config
.minor_version
== 1 &&
393 screen
->max_gl_compat_version
< 31)
394 mesa_api
= API_OPENGL_CORE
;
396 /* The latest version of EGL_KHR_create_context spec says:
398 * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
399 * EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
400 * [...] This bit is supported for OpenGL and OpenGL ES contexts.
402 * No other EGL_CONTEXT_OPENGL_*_BIT is legal for an ES context.
404 * However, Mesa's EGL layer translates the context attribute
405 * EGL_CONTEXT_OPENGL_ROBUST_ACCESS into the context flag
406 * __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS. That attribute is legal for ES
407 * (with EGL 1.5 or EGL_EXT_create_context_robustness) and GL (only with
410 * From the EGL_EXT_create_context_robustness spec:
412 * This extension is written against the OpenGL ES 2.0 Specification
413 * but can apply to OpenGL ES 1.1 and up.
415 * From the EGL 1.5 (2014.08.27) spec, p55:
417 * If the EGL_CONTEXT_OPENGL_ROBUST_ACCESS attribute is set to
418 * EGL_TRUE, a context supporting robust buffer access will be created.
419 * OpenGL contexts must support the GL_ARB_robustness extension, or
420 * equivalent core API functional- ity. OpenGL ES contexts must support
421 * the GL_EXT_robustness extension, or equivalent core API
424 if (mesa_api
!= API_OPENGL_COMPAT
425 && mesa_api
!= API_OPENGL_CORE
426 && (ctx_config
.flags
& ~(__DRI_CTX_FLAG_DEBUG
|
427 __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS
|
428 __DRI_CTX_FLAG_NO_ERROR
))) {
429 *error
= __DRI_CTX_ERROR_BAD_FLAG
;
433 /* There are no forward-compatible contexts before OpenGL 3.0. The
434 * GLX_ARB_create_context spec says:
436 * "Forward-compatible contexts are defined only for OpenGL versions
439 * Forward-looking contexts are supported by silently converting the
440 * requested API to API_OPENGL_CORE.
442 * In Mesa, a debug context is the same as a regular context.
444 if ((ctx_config
.flags
& __DRI_CTX_FLAG_FORWARD_COMPATIBLE
) != 0) {
445 mesa_api
= API_OPENGL_CORE
;
448 const uint32_t allowed_flags
= (__DRI_CTX_FLAG_DEBUG
449 | __DRI_CTX_FLAG_FORWARD_COMPATIBLE
450 | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS
451 | __DRI_CTX_FLAG_NO_ERROR
);
452 if (ctx_config
.flags
& ~allowed_flags
) {
453 *error
= __DRI_CTX_ERROR_UNKNOWN_FLAG
;
457 if (!validate_context_version(screen
, mesa_api
,
458 ctx_config
.major_version
,
459 ctx_config
.minor_version
,
463 context
= calloc(1, sizeof *context
);
465 *error
= __DRI_CTX_ERROR_NO_MEMORY
;
469 context
->loaderPrivate
= data
;
471 context
->driScreenPriv
= screen
;
472 context
->driDrawablePriv
= NULL
;
473 context
->driReadablePriv
= NULL
;
475 if (!screen
->driver
->CreateContext(mesa_api
, modes
, context
,
476 &ctx_config
, error
, shareCtx
)) {
481 *error
= __DRI_CTX_ERROR_SUCCESS
;
486 driContextSetFlags(struct gl_context
*ctx
, uint32_t flags
)
488 if ((flags
& __DRI_CTX_FLAG_FORWARD_COMPATIBLE
) != 0)
489 ctx
->Const
.ContextFlags
|= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT
;
490 if ((flags
& __DRI_CTX_FLAG_DEBUG
) != 0) {
491 _mesa_set_debug_state_int(ctx
, GL_DEBUG_OUTPUT
, GL_TRUE
);
492 ctx
->Const
.ContextFlags
|= GL_CONTEXT_FLAG_DEBUG_BIT
;
494 if ((flags
& __DRI_CTX_FLAG_NO_ERROR
) != 0)
495 ctx
->Const
.ContextFlags
|= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
;
498 static __DRIcontext
*
499 driCreateNewContextForAPI(__DRIscreen
*screen
, int api
,
500 const __DRIconfig
*config
,
501 __DRIcontext
*shared
, void *data
)
505 return driCreateContextAttribs(screen
, api
, config
, shared
, 0, NULL
,
509 static __DRIcontext
*
510 driCreateNewContext(__DRIscreen
*screen
, const __DRIconfig
*config
,
511 __DRIcontext
*shared
, void *data
)
513 return driCreateNewContextForAPI(screen
, __DRI_API_OPENGL
,
514 config
, shared
, data
);
518 * Destroy the per-context private information.
521 * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
522 * drmDestroyContext(), and finally frees \p contextPrivate.
525 driDestroyContext(__DRIcontext
*pcp
)
528 pcp
->driScreenPriv
->driver
->DestroyContext(pcp
);
534 driCopyContext(__DRIcontext
*dest
, __DRIcontext
*src
, unsigned long mask
)
545 /*****************************************************************/
546 /** \name Context (un)binding functions */
547 /*****************************************************************/
550 static void dri_get_drawable(__DRIdrawable
*pdp
);
551 static void dri_put_drawable(__DRIdrawable
*pdp
);
554 * This function takes both a read buffer and a draw buffer. This is needed
555 * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
558 static int driBindContext(__DRIcontext
*pcp
,
563 ** Assume error checking is done properly in glXMakeCurrent before
564 ** calling driUnbindContext.
570 /* Bind the drawable to the context */
571 pcp
->driDrawablePriv
= pdp
;
572 pcp
->driReadablePriv
= prp
;
574 pdp
->driContextPriv
= pcp
;
575 dri_get_drawable(pdp
);
577 if (prp
&& pdp
!= prp
) {
578 dri_get_drawable(prp
);
581 return pcp
->driScreenPriv
->driver
->MakeCurrent(pcp
, pdp
, prp
);
587 * \param scrn the screen.
590 * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
593 * This function calls __DriverAPIRec::UnbindContext, and then decrements
594 * __DRIdrawableRec::refcount which must be non-zero for a successful
597 * While casting the opaque private pointers associated with the parameters
598 * into their respective real types it also assures they are not \c NULL.
600 static int driUnbindContext(__DRIcontext
*pcp
)
606 ** Assume error checking is done properly in glXMakeCurrent before
607 ** calling driUnbindContext.
614 ** Call driUnbindContext before checking for valid drawables
615 ** to handle surfaceless contexts properly.
617 pcp
->driScreenPriv
->driver
->UnbindContext(pcp
);
619 pdp
= pcp
->driDrawablePriv
;
620 prp
= pcp
->driReadablePriv
;
622 /* already unbound */
627 if (pdp
->refcount
== 0) {
632 dri_put_drawable(pdp
);
635 if (prp
->refcount
== 0) {
640 dri_put_drawable(prp
);
643 pcp
->driDrawablePriv
= NULL
;
644 pcp
->driReadablePriv
= NULL
;
652 static void dri_get_drawable(__DRIdrawable
*pdp
)
657 static void dri_put_drawable(__DRIdrawable
*pdp
)
664 pdp
->driScreenPriv
->driver
->DestroyBuffer(pdp
);
669 static __DRIdrawable
*
670 driCreateNewDrawable(__DRIscreen
*screen
,
671 const __DRIconfig
*config
,
674 __DRIdrawable
*pdraw
;
676 assert(data
!= NULL
);
678 pdraw
= malloc(sizeof *pdraw
);
682 pdraw
->loaderPrivate
= data
;
684 pdraw
->driScreenPriv
= screen
;
685 pdraw
->driContextPriv
= NULL
;
687 pdraw
->lastStamp
= 0;
691 dri_get_drawable(pdraw
);
693 if (!screen
->driver
->CreateBuffer(screen
, pdraw
, &config
->modes
,
699 pdraw
->dri2
.stamp
= pdraw
->lastStamp
+ 1;
705 driDestroyDrawable(__DRIdrawable
*pdp
)
708 * The loader's data structures are going away, even if pdp itself stays
709 * around for the time being because it is currently bound. This happens
710 * when a currently bound GLX pixmap is destroyed.
712 * Clear out the pointer back into the loader's data structures to avoid
713 * accessing an outdated pointer.
715 pdp
->loaderPrivate
= NULL
;
717 dri_put_drawable(pdp
);
721 dri2AllocateBuffer(__DRIscreen
*screen
,
722 unsigned int attachment
, unsigned int format
,
723 int width
, int height
)
725 return screen
->driver
->AllocateBuffer(screen
, attachment
, format
,
730 dri2ReleaseBuffer(__DRIscreen
*screen
, __DRIbuffer
*buffer
)
732 screen
->driver
->ReleaseBuffer(screen
, buffer
);
737 dri2ConfigQueryb(__DRIscreen
*screen
, const char *var
, unsigned char *val
)
739 if (!driCheckOption(&screen
->optionCache
, var
, DRI_BOOL
))
742 *val
= driQueryOptionb(&screen
->optionCache
, var
);
748 dri2ConfigQueryi(__DRIscreen
*screen
, const char *var
, int *val
)
750 if (!driCheckOption(&screen
->optionCache
, var
, DRI_INT
) &&
751 !driCheckOption(&screen
->optionCache
, var
, DRI_ENUM
))
754 *val
= driQueryOptioni(&screen
->optionCache
, var
);
760 dri2ConfigQueryf(__DRIscreen
*screen
, const char *var
, float *val
)
762 if (!driCheckOption(&screen
->optionCache
, var
, DRI_FLOAT
))
765 *val
= driQueryOptionf(&screen
->optionCache
, var
);
771 driGetAPIMask(__DRIscreen
*screen
)
773 return screen
->api_mask
;
777 * swrast swapbuffers entrypoint.
779 * DRI2 implements this inside the loader with only flushes handled by the
783 driSwapBuffers(__DRIdrawable
*pdp
)
785 assert(pdp
->driScreenPriv
->swrast_loader
);
787 pdp
->driScreenPriv
->driver
->SwapBuffers(pdp
);
790 /** Core interface */
791 const __DRIcoreExtension driCoreExtension
= {
792 .base
= { __DRI_CORE
, 2 },
794 .createNewScreen
= NULL
,
795 .destroyScreen
= driDestroyScreen
,
796 .getExtensions
= driGetExtensions
,
797 .getConfigAttrib
= driGetConfigAttrib
,
798 .indexConfigAttrib
= driIndexConfigAttrib
,
799 .createNewDrawable
= NULL
,
800 .destroyDrawable
= driDestroyDrawable
,
801 .swapBuffers
= driSwapBuffers
, /* swrast */
802 .createNewContext
= driCreateNewContext
, /* swrast */
803 .copyContext
= driCopyContext
,
804 .destroyContext
= driDestroyContext
,
805 .bindContext
= driBindContext
,
806 .unbindContext
= driUnbindContext
809 /** DRI2 interface */
810 const __DRIdri2Extension driDRI2Extension
= {
811 .base
= { __DRI_DRI2
, 4 },
813 .createNewScreen
= dri2CreateNewScreen
,
814 .createNewDrawable
= driCreateNewDrawable
,
815 .createNewContext
= driCreateNewContext
,
816 .getAPIMask
= driGetAPIMask
,
817 .createNewContextForAPI
= driCreateNewContextForAPI
,
818 .allocateBuffer
= dri2AllocateBuffer
,
819 .releaseBuffer
= dri2ReleaseBuffer
,
820 .createContextAttribs
= driCreateContextAttribs
,
821 .createNewScreen2
= driCreateNewScreen2
,
824 const __DRIswrastExtension driSWRastExtension
= {
825 .base
= { __DRI_SWRAST
, 4 },
827 .createNewScreen
= driSWRastCreateNewScreen
,
828 .createNewDrawable
= driCreateNewDrawable
,
829 .createNewContextForAPI
= driCreateNewContextForAPI
,
830 .createContextAttribs
= driCreateContextAttribs
,
831 .createNewScreen2
= driSWRastCreateNewScreen2
,
834 const __DRI2configQueryExtension dri2ConfigQueryExtension
= {
835 .base
= { __DRI2_CONFIG_QUERY
, 1 },
837 .configQueryb
= dri2ConfigQueryb
,
838 .configQueryi
= dri2ConfigQueryi
,
839 .configQueryf
= dri2ConfigQueryf
,
842 const __DRI2flushControlExtension dri2FlushControlExtension
= {
843 .base
= { __DRI2_FLUSH_CONTROL
, 1 }
847 dri2InvalidateDrawable(__DRIdrawable
*drawable
)
849 drawable
->dri2
.stamp
++;
853 * Check that the gl_framebuffer associated with dPriv is the right size.
854 * Resize the gl_framebuffer if needed.
855 * It's expected that the dPriv->driverPrivate member points to a
856 * gl_framebuffer object.
859 driUpdateFramebufferSize(struct gl_context
*ctx
, const __DRIdrawable
*dPriv
)
861 struct gl_framebuffer
*fb
= (struct gl_framebuffer
*) dPriv
->driverPrivate
;
862 if (fb
&& (dPriv
->w
!= fb
->Width
|| dPriv
->h
!= fb
->Height
)) {
863 _mesa_resize_framebuffer(ctx
, fb
, dPriv
->w
, dPriv
->h
);
864 /* if the driver needs the hw lock for ResizeBuffers, the drawable
865 might have changed again by now */
866 assert(fb
->Width
== dPriv
->w
);
867 assert(fb
->Height
== dPriv
->h
);
872 * Note: the first match is returned, which is important for formats like
873 * __DRI_IMAGE_FORMAT_R8 which maps to both MESA_FORMAT_{R,L}_UNORM8
875 static const struct {
876 uint32_t image_format
;
877 mesa_format mesa_format
;
878 } format_mapping
[] = {
880 .image_format
= __DRI_IMAGE_FORMAT_RGB565
,
881 .mesa_format
= MESA_FORMAT_B5G6R5_UNORM
,
884 .image_format
= __DRI_IMAGE_FORMAT_ARGB1555
,
885 .mesa_format
= MESA_FORMAT_B5G5R5A1_UNORM
,
888 .image_format
= __DRI_IMAGE_FORMAT_XRGB8888
,
889 .mesa_format
= MESA_FORMAT_B8G8R8X8_UNORM
,
892 .image_format
= __DRI_IMAGE_FORMAT_ABGR16161616F
,
893 .mesa_format
= MESA_FORMAT_RGBA_FLOAT16
,
896 .image_format
= __DRI_IMAGE_FORMAT_XBGR16161616F
,
897 .mesa_format
= MESA_FORMAT_RGBX_FLOAT16
,
900 .image_format
= __DRI_IMAGE_FORMAT_ARGB2101010
,
901 .mesa_format
= MESA_FORMAT_B10G10R10A2_UNORM
,
904 .image_format
= __DRI_IMAGE_FORMAT_XRGB2101010
,
905 .mesa_format
= MESA_FORMAT_B10G10R10X2_UNORM
,
908 .image_format
= __DRI_IMAGE_FORMAT_ABGR2101010
,
909 .mesa_format
= MESA_FORMAT_R10G10B10A2_UNORM
,
912 .image_format
= __DRI_IMAGE_FORMAT_XBGR2101010
,
913 .mesa_format
= MESA_FORMAT_R10G10B10X2_UNORM
,
916 .image_format
= __DRI_IMAGE_FORMAT_ARGB8888
,
917 .mesa_format
= MESA_FORMAT_B8G8R8A8_UNORM
,
920 .image_format
= __DRI_IMAGE_FORMAT_ABGR8888
,
921 .mesa_format
= MESA_FORMAT_R8G8B8A8_UNORM
,
924 .image_format
= __DRI_IMAGE_FORMAT_XBGR8888
,
925 .mesa_format
= MESA_FORMAT_R8G8B8X8_UNORM
,
928 .image_format
= __DRI_IMAGE_FORMAT_R8
,
929 .mesa_format
= MESA_FORMAT_R_UNORM8
,
932 .image_format
= __DRI_IMAGE_FORMAT_R8
,
933 .mesa_format
= MESA_FORMAT_L_UNORM8
,
936 .image_format
= __DRI_IMAGE_FORMAT_GR88
,
937 .mesa_format
= MESA_FORMAT_R8G8_UNORM
,
939 #ifdef PIPE_ARCH_LITTLE_ENDIAN
941 .image_format
= __DRI_IMAGE_FORMAT_GR88
,
942 .mesa_format
= MESA_FORMAT_LA_UNORM8
,
946 .image_format
= __DRI_IMAGE_FORMAT_SABGR8
,
947 .mesa_format
= MESA_FORMAT_R8G8B8A8_SRGB
,
950 .image_format
= __DRI_IMAGE_FORMAT_SARGB8
,
951 .mesa_format
= MESA_FORMAT_B8G8R8A8_SRGB
,
954 .image_format
= __DRI_IMAGE_FORMAT_R16
,
955 .mesa_format
= MESA_FORMAT_R_UNORM16
,
958 .image_format
= __DRI_IMAGE_FORMAT_R16
,
959 .mesa_format
= MESA_FORMAT_L_UNORM16
,
962 .image_format
= __DRI_IMAGE_FORMAT_GR1616
,
963 .mesa_format
= MESA_FORMAT_R16G16_UNORM
,
965 #ifdef PIPE_ARCH_LITTLE_ENDIAN
967 .image_format
= __DRI_IMAGE_FORMAT_GR1616
,
968 .mesa_format
= MESA_FORMAT_LA_UNORM16
,
974 driGLFormatToImageFormat(mesa_format format
)
976 for (size_t i
= 0; i
< ARRAY_SIZE(format_mapping
); i
++)
977 if (format_mapping
[i
].mesa_format
== format
)
978 return format_mapping
[i
].image_format
;
980 return __DRI_IMAGE_FORMAT_NONE
;
984 driImageFormatToGLFormat(uint32_t image_format
)
986 for (size_t i
= 0; i
< ARRAY_SIZE(format_mapping
); i
++)
987 if (format_mapping
[i
].image_format
== image_format
)
988 return format_mapping
[i
].mesa_format
;
990 return MESA_FORMAT_NONE
;
993 /** Image driver interface */
994 const __DRIimageDriverExtension driImageDriverExtension
= {
995 .base
= { __DRI_IMAGE_DRIVER
, 1 },
997 .createNewScreen2
= driCreateNewScreen2
,
998 .createNewDrawable
= driCreateNewDrawable
,
999 .getAPIMask
= driGetAPIMask
,
1000 .createContextAttribs
= driCreateContextAttribs
,
1003 /* swrast copy sub buffer entrypoint. */
1004 static void driCopySubBuffer(__DRIdrawable
*pdp
, int x
, int y
,
1007 assert(pdp
->driScreenPriv
->swrast_loader
);
1009 pdp
->driScreenPriv
->driver
->CopySubBuffer(pdp
, x
, y
, w
, h
);
1012 /* for swrast only */
1013 const __DRIcopySubBufferExtension driCopySubBufferExtension
= {
1014 .base
= { __DRI_COPY_SUB_BUFFER
, 1 },
1016 .copySubBuffer
= driCopySubBuffer
,
1019 const __DRInoErrorExtension dri2NoErrorExtension
= {
1020 .base
= { __DRI2_NO_ERROR
, 1 },