2 * Copyright © 2007 Red Hat, Inc
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of Red Hat,
9 * Inc not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission. Red Hat, Inc makes no representations about the
12 * suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
15 * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL RED HAT, INC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
36 #include <GL/internal/dri_interface.h>
37 #include <GL/glxtokens.h>
39 #include <windowstr.h>
42 #define _XF86DRI_SERVER_
47 #include "glxserver.h"
49 #include "glxdricommon.h"
50 #include <GL/glxtokens.h>
52 #include "extension_string.h"
54 typedef struct __GLXDRIscreen __GLXDRIscreen
;
55 typedef struct __GLXDRIcontext __GLXDRIcontext
;
56 typedef struct __GLXDRIdrawable __GLXDRIdrawable
;
58 #ifdef __DRI2_ROBUSTNESS
59 #define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG \
60 | __DRI_CTX_FLAG_FORWARD_COMPATIBLE \
61 | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
63 #define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG \
64 | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)
67 struct __GLXDRIscreen
{
69 __DRIscreen
*driScreen
;
73 xf86EnterVTProc
*enterVT
;
74 xf86LeaveVTProc
*leaveVT
;
76 const __DRIcoreExtension
*core
;
77 const __DRIdri2Extension
*dri2
;
78 const __DRI2flushExtension
*flush
;
79 const __DRIcopySubBufferExtension
*copySubBuffer
;
80 const __DRIswapControlExtension
*swapControl
;
81 const __DRItexBufferExtension
*texBuffer
;
82 const __DRIconfig
**driConfigs
;
84 unsigned char glx_enable_bits
[__GLX_EXT_BYTES
];
87 struct __GLXDRIcontext
{
89 __DRIcontext
*driContext
;
92 #define MAX_DRAWABLE_BUFFERS 5
94 struct __GLXDRIdrawable
{
96 __DRIdrawable
*driDrawable
;
97 __GLXDRIscreen
*screen
;
99 /* Dimensions as last reported by DRI2GetBuffers. */
102 __DRIbuffer buffers
[MAX_DRAWABLE_BUFFERS
];
108 __glXDRIdrawableDestroy(__GLXdrawable
* drawable
)
110 __GLXDRIdrawable
*private = (__GLXDRIdrawable
*) drawable
;
111 const __DRIcoreExtension
*core
= private->screen
->core
;
113 FreeResource(private->dri2_id
, FALSE
);
115 (*core
->destroyDrawable
) (private->driDrawable
);
117 __glXDrawableRelease(drawable
);
123 __glXDRIdrawableCopySubBuffer(__GLXdrawable
* drawable
,
124 int x
, int y
, int w
, int h
)
126 __GLXDRIdrawable
*private = (__GLXDRIdrawable
*) drawable
;
131 box
.y1
= private->height
- y
- h
;
133 box
.y2
= private->height
- y
;
134 RegionInit(®ion
, &box
, 0);
136 DRI2CopyRegion(drawable
->pDraw
, ®ion
,
137 DRI2BufferFrontLeft
, DRI2BufferBackLeft
);
141 __glXDRIdrawableWaitX(__GLXdrawable
* drawable
)
143 __GLXDRIdrawable
*private = (__GLXDRIdrawable
*) drawable
;
149 box
.x2
= private->width
;
150 box
.y2
= private->height
;
151 RegionInit(®ion
, &box
, 0);
153 DRI2CopyRegion(drawable
->pDraw
, ®ion
,
154 DRI2BufferFakeFrontLeft
, DRI2BufferFrontLeft
);
158 __glXDRIdrawableWaitGL(__GLXdrawable
* drawable
)
160 __GLXDRIdrawable
*private = (__GLXDRIdrawable
*) drawable
;
166 box
.x2
= private->width
;
167 box
.y2
= private->height
;
168 RegionInit(®ion
, &box
, 0);
170 DRI2CopyRegion(drawable
->pDraw
, ®ion
,
171 DRI2BufferFrontLeft
, DRI2BufferFakeFrontLeft
);
175 __glXdriSwapEvent(ClientPtr client
, void *data
, int type
, CARD64 ust
,
176 CARD64 msc
, CARD32 sbc
)
178 __GLXdrawable
*drawable
= data
;
181 case DRI2_EXCHANGE_COMPLETE
:
182 glx_type
= GLX_EXCHANGE_COMPLETE_INTEL
;
185 /* unknown swap completion type,
186 * BLIT is a reasonable default, so
189 case DRI2_BLIT_COMPLETE
:
190 glx_type
= GLX_BLIT_COMPLETE_INTEL
;
192 case DRI2_FLIP_COMPLETE
:
193 glx_type
= GLX_FLIP_COMPLETE_INTEL
;
197 __glXsendSwapEvent(drawable
, glx_type
, ust
, msc
, sbc
);
201 * Copy or flip back to front, honoring the swap interval if possible.
203 * If the kernel supports it, we request an event for the frame when the
204 * swap should happen, then perform the copy when we receive it.
207 __glXDRIdrawableSwapBuffers(ClientPtr client
, __GLXdrawable
* drawable
)
209 __GLXDRIdrawable
*priv
= (__GLXDRIdrawable
*) drawable
;
210 __GLXDRIscreen
*screen
= priv
->screen
;
213 #if __DRI2_FLUSH_VERSION >= 3
215 (*screen
->flush
->flush
) (priv
->driDrawable
);
216 (*screen
->flush
->invalidate
) (priv
->driDrawable
);
220 (*screen
->flush
->flushInvalidate
) (priv
->driDrawable
);
223 if (DRI2SwapBuffers(client
, drawable
->pDraw
, 0, 0, 0, &unused
,
224 __glXdriSwapEvent
, drawable
) != Success
)
231 __glXDRIdrawableSwapInterval(__GLXdrawable
* drawable
, int interval
)
233 if (interval
<= 0) /* || interval > BIGNUM? */
234 return GLX_BAD_VALUE
;
236 DRI2SwapInterval(drawable
->pDraw
, interval
);
242 __glXDRIcontextDestroy(__GLXcontext
* baseContext
)
244 __GLXDRIcontext
*context
= (__GLXDRIcontext
*) baseContext
;
245 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) context
->base
.pGlxScreen
;
247 (*screen
->core
->destroyContext
) (context
->driContext
);
248 __glXContextDestroy(&context
->base
);
253 __glXDRIcontextMakeCurrent(__GLXcontext
* baseContext
)
255 __GLXDRIcontext
*context
= (__GLXDRIcontext
*) baseContext
;
256 __GLXDRIdrawable
*draw
= (__GLXDRIdrawable
*) baseContext
->drawPriv
;
257 __GLXDRIdrawable
*read
= (__GLXDRIdrawable
*) baseContext
->readPriv
;
258 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) context
->base
.pGlxScreen
;
260 return (*screen
->core
->bindContext
) (context
->driContext
,
261 draw
->driDrawable
, read
->driDrawable
);
265 __glXDRIcontextLoseCurrent(__GLXcontext
* baseContext
)
267 __GLXDRIcontext
*context
= (__GLXDRIcontext
*) baseContext
;
268 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) context
->base
.pGlxScreen
;
270 return (*screen
->core
->unbindContext
) (context
->driContext
);
274 __glXDRIcontextCopy(__GLXcontext
* baseDst
, __GLXcontext
* baseSrc
,
277 __GLXDRIcontext
*dst
= (__GLXDRIcontext
*) baseDst
;
278 __GLXDRIcontext
*src
= (__GLXDRIcontext
*) baseSrc
;
279 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) dst
->base
.pGlxScreen
;
281 return (*screen
->core
->copyContext
) (dst
->driContext
,
282 src
->driContext
, mask
);
286 __glXDRIcontextWait(__GLXcontext
* baseContext
,
287 __GLXclientState
* cl
, int *error
)
289 if (DRI2WaitSwap(cl
->client
, baseContext
->drawPriv
->pDraw
)) {
290 *error
= cl
->client
->noClientException
;
297 #ifdef __DRI_TEX_BUFFER
300 __glXDRIbindTexImage(__GLXcontext
* baseContext
,
301 int buffer
, __GLXdrawable
* glxPixmap
)
303 __GLXDRIdrawable
*drawable
= (__GLXDRIdrawable
*) glxPixmap
;
304 const __DRItexBufferExtension
*texBuffer
= drawable
->screen
->texBuffer
;
305 __GLXDRIcontext
*context
= (__GLXDRIcontext
*) baseContext
;
307 if (texBuffer
== NULL
)
310 #if __DRI_TEX_BUFFER_VERSION >= 2
311 if (texBuffer
->base
.version
>= 2 && texBuffer
->setTexBuffer2
!= NULL
) {
312 (*texBuffer
->setTexBuffer2
) (context
->driContext
,
314 glxPixmap
->format
, drawable
->driDrawable
);
319 texBuffer
->setTexBuffer(context
->driContext
,
320 glxPixmap
->target
, drawable
->driDrawable
);
327 __glXDRIreleaseTexImage(__GLXcontext
* baseContext
,
328 int buffer
, __GLXdrawable
* pixmap
)
330 /* FIXME: Just unbind the texture? */
337 __glXDRIbindTexImage(__GLXcontext
* baseContext
,
338 int buffer
, __GLXdrawable
* glxPixmap
)
344 __glXDRIreleaseTexImage(__GLXcontext
* baseContext
,
345 int buffer
, __GLXdrawable
* pixmap
)
352 static __GLXtextureFromPixmap __glXDRItextureFromPixmap
= {
353 __glXDRIbindTexImage
,
354 __glXDRIreleaseTexImage
358 __glXDRIscreenDestroy(__GLXscreen
* baseScreen
)
362 ScrnInfoPtr pScrn
= xf86ScreenToScrn(baseScreen
->pScreen
);
363 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) baseScreen
;
365 (*screen
->core
->destroyScreen
) (screen
->driScreen
);
367 dlclose(screen
->driver
);
369 __glXScreenDestroy(baseScreen
);
371 if (screen
->driConfigs
) {
372 for (i
= 0; screen
->driConfigs
[i
] != NULL
; i
++)
373 free((__DRIconfig
**) screen
->driConfigs
[i
]);
374 free(screen
->driConfigs
);
377 pScrn
->EnterVT
= screen
->enterVT
;
378 pScrn
->LeaveVT
= screen
->leaveVT
;
384 dri2_convert_glx_attribs(__GLXDRIscreen
*screen
, unsigned num_attribs
,
385 const uint32_t *attribs
,
386 unsigned *major_ver
, unsigned *minor_ver
,
387 uint32_t *flags
, int *api
, int *reset
, unsigned *error
)
391 if (num_attribs
== 0)
394 if (attribs
== NULL
) {
395 *error
= BadImplementation
;
401 #ifdef __DRI2_ROBUSTNESS
402 *reset
= __DRI_CTX_RESET_NO_NOTIFICATION
;
407 for (i
= 0; i
< num_attribs
; i
++) {
408 switch (attribs
[i
* 2]) {
409 case GLX_CONTEXT_MAJOR_VERSION_ARB
:
410 *major_ver
= attribs
[i
* 2 + 1];
412 case GLX_CONTEXT_MINOR_VERSION_ARB
:
413 *minor_ver
= attribs
[i
* 2 + 1];
415 case GLX_CONTEXT_FLAGS_ARB
:
416 *flags
= attribs
[i
* 2 + 1];
418 case GLX_RENDER_TYPE
:
420 case GLX_CONTEXT_PROFILE_MASK_ARB
:
421 switch (attribs
[i
* 2 + 1]) {
422 case GLX_CONTEXT_CORE_PROFILE_BIT_ARB
:
423 *api
= __DRI_API_OPENGL_CORE
;
425 case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
:
426 *api
= __DRI_API_OPENGL
;
428 case GLX_CONTEXT_ES2_PROFILE_BIT_EXT
:
429 *api
= __DRI_API_GLES2
;
432 *error
= __glXError(GLXBadProfileARB
);
436 #ifdef __DRI2_ROBUSTNESS
437 case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
:
438 if (screen
->dri2
->base
.version
>= 4) {
443 switch (attribs
[i
* 2 + 1]) {
444 case GLX_NO_RESET_NOTIFICATION_ARB
:
445 *reset
= __DRI_CTX_RESET_NO_NOTIFICATION
;
447 case GLX_LOSE_CONTEXT_ON_RESET_ARB
:
448 *reset
= __DRI_CTX_RESET_LOSE_CONTEXT
;
457 /* If an unknown attribute is received, fail.
464 /* Unknown flag value.
466 if ((*flags
& ~ALL_DRI_CTX_FLAGS
) != 0) {
471 /* If the core profile is requested for a GL version is less than 3.2,
472 * request the non-core profile from the DRI driver. The core profile
473 * only makes sense for GL versions >= 3.2, and many DRI drivers that
474 * don't support OpenGL 3.2 may fail the request for a core profile.
476 if (*api
== __DRI_API_OPENGL_CORE
477 && (*major_ver
< 3 || (*major_ver
== 3 && *minor_ver
< 2))) {
478 *api
= __DRI_API_OPENGL
;
486 create_driver_context(__GLXDRIcontext
* context
,
487 __GLXDRIscreen
* screen
,
488 __GLXDRIconfig
* config
,
489 __DRIcontext
* driShare
,
490 unsigned num_attribs
,
491 const uint32_t *attribs
,
494 context
->driContext
= NULL
;
496 #if __DRI_DRI2_VERSION >= 3
497 if (screen
->dri2
->base
.version
>= 3) {
498 uint32_t ctx_attribs
[3 * 2];
499 unsigned num_ctx_attribs
= 0;
500 unsigned dri_err
= 0;
505 int api
= __DRI_API_OPENGL
;
507 if (num_attribs
!= 0) {
508 if (!dri2_convert_glx_attribs(screen
, num_attribs
, attribs
,
509 &major_ver
, &minor_ver
,
510 &flags
, &api
, &reset
,
514 ctx_attribs
[num_ctx_attribs
++] = __DRI_CTX_ATTRIB_MAJOR_VERSION
;
515 ctx_attribs
[num_ctx_attribs
++] = major_ver
;
516 ctx_attribs
[num_ctx_attribs
++] = __DRI_CTX_ATTRIB_MINOR_VERSION
;
517 ctx_attribs
[num_ctx_attribs
++] = minor_ver
;
520 ctx_attribs
[num_ctx_attribs
++] = __DRI_CTX_ATTRIB_FLAGS
;
522 /* The current __DRI_CTX_FLAG_* values are identical to the
523 * GLX_CONTEXT_*_BIT values.
525 ctx_attribs
[num_ctx_attribs
++] = flags
;
528 #ifdef __DRI2_ROBUSTNESS
529 if (reset
!= __DRI_CTX_RESET_NO_NOTIFICATION
) {
530 ctx_attribs
[num_ctx_attribs
++] =
531 __DRI_CTX_ATTRIB_RESET_STRATEGY
;
532 ctx_attribs
[num_ctx_attribs
++] = reset
;
537 context
->driContext
=
538 (*screen
->dri2
->createContextAttribs
)(screen
->driScreen
,
548 case __DRI_CTX_ERROR_SUCCESS
:
551 case __DRI_CTX_ERROR_NO_MEMORY
:
554 case __DRI_CTX_ERROR_BAD_API
:
555 *error
= __glXError(GLXBadProfileARB
);
557 case __DRI_CTX_ERROR_BAD_VERSION
:
558 case __DRI_CTX_ERROR_BAD_FLAG
:
559 *error
= __glXError(GLXBadFBConfig
);
561 case __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE
:
562 case __DRI_CTX_ERROR_UNKNOWN_FLAG
:
572 if (num_attribs
!= 0) {
577 context
->driContext
=
578 (*screen
->dri2
->createNewContext
) (screen
->driScreen
,
583 static __GLXcontext
*
584 __glXDRIscreenCreateContext(__GLXscreen
* baseScreen
,
585 __GLXconfig
* glxConfig
,
586 __GLXcontext
* baseShareContext
,
587 unsigned num_attribs
,
588 const uint32_t *attribs
,
591 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) baseScreen
;
592 __GLXDRIcontext
*context
, *shareContext
;
593 __GLXDRIconfig
*config
= (__GLXDRIconfig
*) glxConfig
;
594 __DRIcontext
*driShare
;
596 shareContext
= (__GLXDRIcontext
*) baseShareContext
;
598 driShare
= shareContext
->driContext
;
602 context
= calloc(1, sizeof *context
);
603 if (context
== NULL
) {
608 context
->base
.destroy
= __glXDRIcontextDestroy
;
609 context
->base
.makeCurrent
= __glXDRIcontextMakeCurrent
;
610 context
->base
.loseCurrent
= __glXDRIcontextLoseCurrent
;
611 context
->base
.copy
= __glXDRIcontextCopy
;
612 context
->base
.textureFromPixmap
= &__glXDRItextureFromPixmap
;
613 context
->base
.wait
= __glXDRIcontextWait
;
615 create_driver_context(context
, screen
, config
, driShare
, num_attribs
,
617 if (context
->driContext
== NULL
) {
622 return &context
->base
;
626 __glXDRIinvalidateBuffers(DrawablePtr pDraw
, void *priv
, XID id
)
628 #if __DRI2_FLUSH_VERSION >= 3
629 __GLXDRIdrawable
*private = priv
;
630 __GLXDRIscreen
*screen
= private->screen
;
633 (*screen
->flush
->invalidate
) (private->driDrawable
);
637 static __GLXdrawable
*
638 __glXDRIscreenCreateDrawable(ClientPtr client
,
639 __GLXscreen
* screen
,
642 int type
, XID glxDrawId
, __GLXconfig
* glxConfig
)
644 __GLXDRIscreen
*driScreen
= (__GLXDRIscreen
*) screen
;
645 __GLXDRIconfig
*config
= (__GLXDRIconfig
*) glxConfig
;
646 __GLXDRIdrawable
*private;
648 private = calloc(1, sizeof *private);
652 private->screen
= driScreen
;
653 if (!__glXDrawableInit(&private->base
, screen
,
654 pDraw
, type
, glxDrawId
, glxConfig
)) {
659 private->base
.destroy
= __glXDRIdrawableDestroy
;
660 private->base
.swapBuffers
= __glXDRIdrawableSwapBuffers
;
661 private->base
.copySubBuffer
= __glXDRIdrawableCopySubBuffer
;
662 private->base
.waitGL
= __glXDRIdrawableWaitGL
;
663 private->base
.waitX
= __glXDRIdrawableWaitX
;
665 if (DRI2CreateDrawable2(client
, pDraw
, drawId
,
666 __glXDRIinvalidateBuffers
, private,
667 &private->dri2_id
)) {
672 private->driDrawable
=
673 (*driScreen
->dri2
->createNewDrawable
) (driScreen
->driScreen
,
674 config
->driConfig
, private);
676 return &private->base
;
680 dri2GetBuffers(__DRIdrawable
* driDrawable
,
681 int *width
, int *height
,
682 unsigned int *attachments
, int count
,
683 int *out_count
, void *loaderPrivate
)
685 __GLXDRIdrawable
*private = loaderPrivate
;
686 DRI2BufferPtr
*buffers
;
690 buffers
= DRI2GetBuffers(private->base
.pDraw
,
691 width
, height
, attachments
, count
, out_count
);
692 if (*out_count
> MAX_DRAWABLE_BUFFERS
) {
697 private->width
= *width
;
698 private->height
= *height
;
700 /* This assumes the DRI2 buffer attachment tokens matches the
701 * __DRIbuffer tokens. */
703 for (i
= 0; i
< *out_count
; i
++) {
704 /* Do not send the real front buffer of a window to the client.
706 if ((private->base
.pDraw
->type
== DRAWABLE_WINDOW
)
707 && (buffers
[i
]->attachment
== DRI2BufferFrontLeft
)) {
711 private->buffers
[j
].attachment
= buffers
[i
]->attachment
;
712 private->buffers
[j
].name
= buffers
[i
]->name
;
713 private->buffers
[j
].pitch
= buffers
[i
]->pitch
;
714 private->buffers
[j
].cpp
= buffers
[i
]->cpp
;
715 private->buffers
[j
].flags
= buffers
[i
]->flags
;
720 return private->buffers
;
724 dri2GetBuffersWithFormat(__DRIdrawable
* driDrawable
,
725 int *width
, int *height
,
726 unsigned int *attachments
, int count
,
727 int *out_count
, void *loaderPrivate
)
729 __GLXDRIdrawable
*private = loaderPrivate
;
730 DRI2BufferPtr
*buffers
;
734 buffers
= DRI2GetBuffersWithFormat(private->base
.pDraw
,
735 width
, height
, attachments
, count
,
737 if (*out_count
> MAX_DRAWABLE_BUFFERS
) {
742 private->width
= *width
;
743 private->height
= *height
;
745 /* This assumes the DRI2 buffer attachment tokens matches the
746 * __DRIbuffer tokens. */
747 for (i
= 0; i
< *out_count
; i
++) {
748 /* Do not send the real front buffer of a window to the client.
750 if ((private->base
.pDraw
->type
== DRAWABLE_WINDOW
)
751 && (buffers
[i
]->attachment
== DRI2BufferFrontLeft
)) {
755 private->buffers
[j
].attachment
= buffers
[i
]->attachment
;
756 private->buffers
[j
].name
= buffers
[i
]->name
;
757 private->buffers
[j
].pitch
= buffers
[i
]->pitch
;
758 private->buffers
[j
].cpp
= buffers
[i
]->cpp
;
759 private->buffers
[j
].flags
= buffers
[i
]->flags
;
764 return private->buffers
;
768 dri2FlushFrontBuffer(__DRIdrawable
* driDrawable
, void *loaderPrivate
)
771 __glXDRIdrawableWaitGL((__GLXdrawable
*) loaderPrivate
);
774 static const __DRIdri2LoaderExtension loaderExtension
= {
775 {__DRI_DRI2_LOADER
, 3},
777 dri2FlushFrontBuffer
,
778 dri2GetBuffersWithFormat
,
781 #ifdef __DRI_USE_INVALIDATE
782 static const __DRIuseInvalidateExtension dri2UseInvalidate
= {
783 {__DRI_USE_INVALIDATE
, 1}
787 static const __DRIextension
*loader_extensions
[] = {
788 &systemTimeExtension
.base
,
789 &loaderExtension
.base
,
790 #ifdef __DRI_USE_INVALIDATE
791 &dri2UseInvalidate
.base
,
797 glxDRIEnterVT(ScrnInfoPtr scrn
)
800 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*)
801 glxGetScreen(xf86ScrnToScreen(scrn
));
803 LogMessage(X_INFO
, "AIGLX: Resuming AIGLX clients after VT switch\n");
805 scrn
->EnterVT
= screen
->enterVT
;
807 ret
= scrn
->EnterVT(scrn
);
809 screen
->enterVT
= scrn
->EnterVT
;
810 scrn
->EnterVT
= glxDRIEnterVT
;
821 glxDRILeaveVT(ScrnInfoPtr scrn
)
823 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*)
824 glxGetScreen(xf86ScrnToScreen(scrn
));
826 LogMessageVerbSigSafe(X_INFO
, -1, "AIGLX: Suspending AIGLX clients for VT switch\n");
830 scrn
->LeaveVT
= screen
->leaveVT
;
831 (*screen
->leaveVT
) (scrn
);
832 screen
->leaveVT
= scrn
->LeaveVT
;
833 scrn
->LeaveVT
= glxDRILeaveVT
;
837 * Initialize extension flags in glx_enable_bits when a new screen is created
839 * @param screen The screen where glx_enable_bits are to be set.
842 initializeExtensions(__GLXDRIscreen
* screen
)
844 ScreenPtr pScreen
= screen
->base
.pScreen
;
845 const __DRIextension
**extensions
;
848 extensions
= screen
->core
->getExtensions(screen
->driScreen
);
850 __glXEnableExtension(screen
->glx_enable_bits
, "GLX_MESA_copy_sub_buffer");
851 LogMessage(X_INFO
, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
854 #if __DRI_DRI2_VERSION >= 3
855 if (screen
->dri2
->base
.version
>= 3) {
856 __glXEnableExtension(screen
->glx_enable_bits
,
857 "GLX_ARB_create_context");
858 __glXEnableExtension(screen
->glx_enable_bits
,
859 "GLX_ARB_create_context_profile");
860 __glXEnableExtension(screen
->glx_enable_bits
,
861 "GLX_EXT_create_context_es2_profile");
862 LogMessage(X_INFO
, "AIGLX: enabled GLX_ARB_create_context\n");
863 LogMessage(X_INFO
, "AIGLX: enabled GLX_ARB_create_context_profile\n");
865 "AIGLX: enabled GLX_EXT_create_context_es2_profile\n");
869 if (DRI2HasSwapControl(pScreen
)) {
870 __glXEnableExtension(screen
->glx_enable_bits
, "GLX_INTEL_swap_event");
871 __glXEnableExtension(screen
->glx_enable_bits
, "GLX_SGI_swap_control");
872 __glXEnableExtension(screen
->glx_enable_bits
, "GLX_MESA_swap_control");
873 LogMessage(X_INFO
, "AIGLX: enabled GLX_INTEL_swap_event\n");
875 "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
878 /* enable EXT_framebuffer_sRGB extension (even if there are no sRGB capable fbconfigs) */
880 __glXEnableExtension(screen
->glx_enable_bits
,
881 "GLX_EXT_framebuffer_sRGB");
882 LogMessage(X_INFO
, "AIGLX: enabled GLX_EXT_framebuffer_sRGB\n");
885 /* enable ARB_fbconfig_float extension (even if there are no float fbconfigs) */
887 __glXEnableExtension(screen
->glx_enable_bits
, "GLX_ARB_fbconfig_float");
888 LogMessage(X_INFO
, "AIGLX: enabled GLX_ARB_fbconfig_float\n");
891 for (i
= 0; extensions
[i
]; i
++) {
892 #ifdef __DRI_READ_DRAWABLE
893 if (strcmp(extensions
[i
]->name
, __DRI_READ_DRAWABLE
) == 0) {
894 __glXEnableExtension(screen
->glx_enable_bits
,
895 "GLX_SGI_make_current_read");
897 LogMessage(X_INFO
, "AIGLX: enabled GLX_SGI_make_current_read\n");
901 #ifdef __DRI_TEX_BUFFER
902 if (strcmp(extensions
[i
]->name
, __DRI_TEX_BUFFER
) == 0) {
903 screen
->texBuffer
= (const __DRItexBufferExtension
*) extensions
[i
];
904 /* GLX_EXT_texture_from_pixmap is always enabled. */
906 "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
911 if (strcmp(extensions
[i
]->name
, __DRI2_FLUSH
) == 0 &&
912 extensions
[i
]->version
>= 3) {
913 screen
->flush
= (__DRI2flushExtension
*) extensions
[i
];
917 #ifdef __DRI2_ROBUSTNESS
918 if (strcmp(extensions
[i
]->name
, __DRI2_ROBUSTNESS
) == 0 &&
919 screen
->dri2
->base
.version
>= 3) {
920 __glXEnableExtension(screen
->glx_enable_bits
,
921 "GLX_ARB_create_context_robustness");
923 "AIGLX: enabled GLX_ARB_create_context_robustness\n");
927 /* Ignore unknown extensions */
932 extern glx_func_ptr
glXGetProcAddressARB(const char *);
935 __glXDRIscreenProbe(ScreenPtr pScreen
)
937 const char *driverName
, *deviceName
;
938 __GLXDRIscreen
*screen
;
940 ScrnInfoPtr pScrn
= xf86ScreenToScrn(pScreen
);
942 screen
= calloc(1, sizeof *screen
);
946 if (!DRI2Connect(serverClient
, pScreen
, DRI2DriverDRI
,
947 &screen
->fd
, &driverName
, &deviceName
)) {
949 "AIGLX: Screen %d is not DRI2 capable\n", pScreen
->myNum
);
953 screen
->base
.destroy
= __glXDRIscreenDestroy
;
954 screen
->base
.createContext
= __glXDRIscreenCreateContext
;
955 screen
->base
.createDrawable
= __glXDRIscreenCreateDrawable
;
956 screen
->base
.swapInterval
= __glXDRIdrawableSwapInterval
;
957 screen
->base
.pScreen
= pScreen
;
959 __glXInitExtensionEnableBits(screen
->glx_enable_bits
);
962 glxProbeDriver(driverName
, (void **) &screen
->core
, __DRI_CORE
, 1,
963 (void **) &screen
->dri2
, __DRI_DRI2
, 1);
964 if (screen
->driver
== NULL
) {
969 (*screen
->dri2
->createNewScreen
) (pScreen
->myNum
,
972 &screen
->driConfigs
, screen
);
974 if (screen
->driScreen
== NULL
) {
975 LogMessage(X_ERROR
, "AIGLX error: Calling driver entry point failed\n");
979 initializeExtensions(screen
);
981 screen
->base
.fbconfigs
= glxConvertConfigs(screen
->core
, screen
->driConfigs
,
986 __glXScreenInit(&screen
->base
, pScreen
);
988 /* The first call simply determines the length of the extension string.
989 * This allows us to allocate some memory to hold the extension string,
990 * but it requires that we call __glXGetExtensionString a second time.
992 buffer_size
= __glXGetExtensionString(screen
->glx_enable_bits
, NULL
);
993 if (buffer_size
> 0) {
994 free(screen
->base
.GLXextensions
);
996 screen
->base
.GLXextensions
= xnfalloc(buffer_size
);
997 (void) __glXGetExtensionString(screen
->glx_enable_bits
,
998 screen
->base
.GLXextensions
);
1001 /* We're going to assume (perhaps incorrectly?) that all DRI2-enabled
1002 * drivers support the required extensions for GLX 1.4. The extensions
1003 * we're assuming are:
1005 * - GLX_SGI_make_current_read (1.3)
1006 * - GLX_SGIX_fbconfig (1.3)
1007 * - GLX_SGIX_pbuffer (1.3)
1008 * - GLX_ARB_multisample (1.4)
1010 screen
->base
.GLXmajor
= 1;
1011 screen
->base
.GLXminor
= 4;
1013 screen
->enterVT
= pScrn
->EnterVT
;
1014 pScrn
->EnterVT
= glxDRIEnterVT
;
1015 screen
->leaveVT
= pScrn
->LeaveVT
;
1016 pScrn
->LeaveVT
= glxDRILeaveVT
;
1018 __glXsetGetProcAddress(glXGetProcAddressARB
);
1020 LogMessage(X_INFO
, "AIGLX: Loaded and initialized %s\n", driverName
);
1022 return &screen
->base
;
1026 dlclose(screen
->driver
);
1030 LogMessage(X_ERROR
, "AIGLX: reverting to software rendering\n");
1035 _X_EXPORT __GLXprovider __glXDRI2Provider
= {
1036 __glXDRIscreenProbe
,