aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/glx
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/glx')
-rw-r--r--xorg-server/glx/glxcmds.c23
-rw-r--r--xorg-server/glx/glxdri.c8
-rw-r--r--xorg-server/glx/glxdri2.c1612
-rw-r--r--xorg-server/glx/glxdriswrast.c8
-rw-r--r--xorg-server/glx/glxscreens.h366
5 files changed, 1015 insertions, 1002 deletions
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c
index e9350e380..c0e8feec2 100644
--- a/xorg-server/glx/glxcmds.c
+++ b/xorg-server/glx/glxcmds.c
@@ -516,8 +516,9 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
return NULL;
- pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
- pDraw, GLX_DRAWABLE_WINDOW,
+ pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
+ pDraw, drawId,
+ GLX_DRAWABLE_WINDOW,
drawId, glxc->config);
/* since we are creating the drawablePrivate, drawId should be new */
@@ -1108,15 +1109,17 @@ __glXDrawableRelease(__GLXdrawable *drawable)
}
static int
-DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
- DrawablePtr pDraw, XID glxDrawableId, int type)
+DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen,
+ __GLXconfig *config, DrawablePtr pDraw, XID drawableId,
+ XID glxDrawableId, int type)
{
__GLXdrawable *pGlxDraw;
if (pGlxScreen->pScreen != pDraw->pScreen)
return BadMatch;
- pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
+ pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw,
+ drawableId, type,
glxDrawableId, config);
if (pGlxDraw == NULL)
return BadAlloc;
@@ -1129,7 +1132,7 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf
/* Add the glx drawable under the XID of the underlying X drawable
* too. That way we'll get a callback in DrawableGone and can
* clean up properly when the drawable is destroyed. */
- if (pDraw->id != glxDrawableId &&
+ if (drawableId != glxDrawableId &&
!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
pGlxDraw->destroy (pGlxDraw);
return BadAlloc;
@@ -1157,7 +1160,7 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config
return BadPixmap;
}
- err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
+ err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId,
glxDrawableId, GLX_DRAWABLE_PIXMAP);
return err;
@@ -1320,7 +1323,8 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
return BadAlloc;
return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
- glxDrawableId, GLX_DRAWABLE_PBUFFER);
+ glxDrawableId, glxDrawableId,
+ GLX_DRAWABLE_PBUFFER);
}
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
@@ -1443,7 +1447,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
return err;
return DoCreateGLXDrawable(client, pGlxScreen, config,
- pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
+ pDraw, req->window,
+ req->glxwindow, GLX_DRAWABLE_WINDOW);
}
int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c
index 7c5e781e6..4bb33bff3 100644
--- a/xorg-server/glx/glxdri.c
+++ b/xorg-server/glx/glxdri.c
@@ -686,10 +686,12 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
}
static __GLXdrawable *
-__glXDRIscreenCreateDrawable(__GLXscreen *screen,
+__glXDRIscreenCreateDrawable(ClientPtr client,
+ __GLXscreen *screen,
DrawablePtr pDraw,
- int type,
XID drawId,
+ int type,
+ XID glxDrawId,
__GLXconfig *glxConfig)
{
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
@@ -703,7 +705,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
return NULL;
if (!__glXDrawableInit(&private->base, screen,
- pDraw, type, drawId, glxConfig)) {
+ pDraw, type, glxDrawId, glxConfig)) {
xfree(private);
return NULL;
}
diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c
index 74d6ebc5d..f1396b54d 100644
--- a/xorg-server/glx/glxdri2.c
+++ b/xorg-server/glx/glxdri2.c
@@ -1,805 +1,807 @@
-/*
- * Copyright © 2007 Red Hat, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of Red Hat,
- * Inc not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Red Hat, Inc makes no representations about the
- * suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
- * NO EVENT SHALL RED HAT, INC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <dlfcn.h>
-
-#include <drm.h>
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-#include <GL/glxtokens.h>
-
-#include <windowstr.h>
-#include <os.h>
-
-#define _XF86DRI_SERVER_
-#include <xf86drm.h>
-#include <xf86.h>
-#include <dri2.h>
-
-#include "glxserver.h"
-#include "glxutil.h"
-#include "glxdricommon.h"
-
-#include "g_disptab.h"
-#include "glapitable.h"
-#include "glapi.h"
-#include "glthread.h"
-#include "dispatch.h"
-#include "extension_string.h"
-
-typedef struct __GLXDRIscreen __GLXDRIscreen;
-typedef struct __GLXDRIcontext __GLXDRIcontext;
-typedef struct __GLXDRIdrawable __GLXDRIdrawable;
-
-struct __GLXDRIscreen {
- __GLXscreen base;
- __DRIscreen *driScreen;
- void *driver;
- int fd;
-
- xf86EnterVTProc *enterVT;
- xf86LeaveVTProc *leaveVT;
-
- const __DRIcoreExtension *core;
- const __DRIdri2Extension *dri2;
- const __DRI2flushExtension *flush;
- const __DRIcopySubBufferExtension *copySubBuffer;
- const __DRIswapControlExtension *swapControl;
- const __DRItexBufferExtension *texBuffer;
-
- unsigned char glx_enable_bits[__GLX_EXT_BYTES];
-};
-
-struct __GLXDRIcontext {
- __GLXcontext base;
- __DRIcontext *driContext;
-};
-
-#define MAX_DRAWABLE_BUFFERS 5
-
-struct __GLXDRIdrawable {
- __GLXdrawable base;
- __DRIdrawable *driDrawable;
- __GLXDRIscreen *screen;
-
- /* Dimensions as last reported by DRI2GetBuffers. */
- int width;
- int height;
- __DRIbuffer buffers[MAX_DRAWABLE_BUFFERS];
- int count;
-};
-
-static void
-__glXDRIdrawableDestroy(__GLXdrawable *drawable)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
- const __DRIcoreExtension *core = private->screen->core;
-
- (*core->destroyDrawable)(private->driDrawable);
-
- __glXDrawableRelease(drawable);
-
- xfree(private);
-}
-
-static void
-__glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
- int x, int y, int w, int h)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
- BoxRec box;
- RegionRec region;
-
- box.x1 = x;
- box.y1 = private->height - y - h;
- box.x2 = x + w;
- box.y2 = private->height - y;
- REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
-
- DRI2CopyRegion(drawable->pDraw, &region,
- DRI2BufferFrontLeft, DRI2BufferBackLeft);
-}
-
-static void
-__glXDRIdrawableWaitX(__GLXdrawable *drawable)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
- BoxRec box;
- RegionRec region;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = private->width;
- box.y2 = private->height;
- REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
-
- DRI2CopyRegion(drawable->pDraw, &region,
- DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
-}
-
-static void
-__glXDRIdrawableWaitGL(__GLXdrawable *drawable)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
- BoxRec box;
- RegionRec region;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = private->width;
- box.y2 = private->height;
- REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
-
- DRI2CopyRegion(drawable->pDraw, &region,
- DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
-}
-
-static void
-__glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust,
- CARD64 msc, CARD64 sbc)
-{
- __GLXdrawable *drawable = data;
- xGLXBufferSwapComplete wire;
-
- if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
- return;
-
- wire.type = __glXEventBase + GLX_BufferSwapComplete;
- switch (type) {
- case DRI2_EXCHANGE_COMPLETE:
- wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL;
- break;
- case DRI2_BLIT_COMPLETE:
- wire.event_type = GLX_BLIT_COMPLETE_INTEL;
- break;
- case DRI2_FLIP_COMPLETE:
- wire.event_type = GLX_FLIP_COMPLETE_INTEL;
- break;
- default:
- /* unknown swap completion type */
- break;
- }
- wire.sequenceNumber = client->sequence;
- wire.drawable = drawable->drawId;
- wire.ust_hi = ust >> 32;
- wire.ust_lo = ust & 0xffffffff;
- wire.msc_hi = msc >> 32;
- wire.msc_lo = msc & 0xffffffff;
- wire.sbc_hi = sbc >> 32;
- wire.sbc_lo = sbc & 0xffffffff;
-
- WriteEventsToClient(client, 1, (xEvent *) &wire);
-}
-
-/*
- * Copy or flip back to front, honoring the swap interval if possible.
- *
- * If the kernel supports it, we request an event for the frame when the
- * swap should happen, then perform the copy when we receive it.
- */
-static GLboolean
-__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
-{
- __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
- __GLXDRIscreen *screen = priv->screen;
- CARD64 unused;
-
-#if __DRI2_FLUSH_VERSION >= 3
- if (screen->flush) {
- (*screen->flush->flush)(priv->driDrawable);
- (*screen->flush->invalidate)(priv->driDrawable);
- }
-#else
- if (screen->flush)
- (*screen->flush->flushInvalidate)(priv->driDrawable);
-#endif
-
- if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused,
- __glXdriSwapEvent, drawable->pDraw) != Success)
- return FALSE;
-
- return TRUE;
-}
-
-static int
-__glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
-{
- if (interval <= 0) /* || interval > BIGNUM? */
- return GLX_BAD_VALUE;
-
- DRI2SwapInterval(drawable->pDraw, interval);
-
- return 0;
-}
-
-static void
-__glXDRIcontextDestroy(__GLXcontext *baseContext)
-{
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
- (*screen->core->destroyContext)(context->driContext);
- __glXContextDestroy(&context->base);
- xfree(context);
-}
-
-static int
-__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
-{
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
- __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
- return (*screen->core->bindContext)(context->driContext,
- draw->driDrawable,
- read->driDrawable);
-}
-
-static int
-__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
-{
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
- return (*screen->core->unbindContext)(context->driContext);
-}
-
-static int
-__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
- unsigned long mask)
-{
- __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
- __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
-
- return (*screen->core->copyContext)(dst->driContext,
- src->driContext, mask);
-}
-
-static int
-__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
-{
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
- __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
- __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
- __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
-
- return (*screen->core->bindContext)(context->driContext,
- draw->driDrawable,
- read->driDrawable);
-}
-
-static Bool
-__glXDRIcontextWait(__GLXcontext *baseContext,
- __GLXclientState *cl, int *error)
-{
- if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) {
- *error = cl->client->noClientException;
- return TRUE;
- }
-
- return FALSE;
-}
-
-#ifdef __DRI_TEX_BUFFER
-
-static int
-__glXDRIbindTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *glxPixmap)
-{
- __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
- const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
- __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
-
- if (texBuffer == NULL)
- return Success;
-
-#if __DRI_TEX_BUFFER_VERSION >= 2
- if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
- (*texBuffer->setTexBuffer2)(context->driContext,
- glxPixmap->target,
- glxPixmap->format,
- drawable->driDrawable);
- } else
-#endif
- {
- texBuffer->setTexBuffer(context->driContext,
- glxPixmap->target,
- drawable->driDrawable);
- }
-
- return Success;
-}
-
-static int
-__glXDRIreleaseTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *pixmap)
-{
- /* FIXME: Just unbind the texture? */
- return Success;
-}
-
-#else
-
-static int
-__glXDRIbindTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *glxPixmap)
-{
- return Success;
-}
-
-static int
-__glXDRIreleaseTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *pixmap)
-{
- return Success;
-}
-
-#endif
-
-static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
- __glXDRIbindTexImage,
- __glXDRIreleaseTexImage
-};
-
-static void
-__glXDRIscreenDestroy(__GLXscreen *baseScreen)
-{
- __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
-
- (*screen->core->destroyScreen)(screen->driScreen);
-
- dlclose(screen->driver);
-
- __glXScreenDestroy(baseScreen);
-
- xfree(screen);
-}
-
-static __GLXcontext *
-__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
- __GLXconfig *glxConfig,
- __GLXcontext *baseShareContext)
-{
- __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
- __GLXDRIcontext *context, *shareContext;
- __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
- __DRIcontext *driShare;
-
- shareContext = (__GLXDRIcontext *) baseShareContext;
- if (shareContext)
- driShare = shareContext->driContext;
- else
- driShare = NULL;
-
- context = xcalloc(1, sizeof *context);
- if (context == NULL)
- return NULL;
-
- context->base.destroy = __glXDRIcontextDestroy;
- context->base.makeCurrent = __glXDRIcontextMakeCurrent;
- context->base.loseCurrent = __glXDRIcontextLoseCurrent;
- context->base.copy = __glXDRIcontextCopy;
- context->base.forceCurrent = __glXDRIcontextForceCurrent;
- context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
- context->base.wait = __glXDRIcontextWait;
-
- context->driContext =
- (*screen->dri2->createNewContext)(screen->driScreen,
- config->driConfig,
- driShare, context);
- if (context->driContext == NULL) {
- xfree(context);
- return NULL;
- }
-
- return &context->base;
-}
-
-static __GLXdrawable *
-__glXDRIscreenCreateDrawable(__GLXscreen *screen,
- DrawablePtr pDraw,
- int type,
- XID drawId,
- __GLXconfig *glxConfig)
-{
- __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
- __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
- __GLXDRIdrawable *private;
-
- private = xcalloc(1, sizeof *private);
- if (private == NULL)
- return NULL;
-
- private->screen = driScreen;
- if (!__glXDrawableInit(&private->base, screen,
- pDraw, type, drawId, glxConfig)) {
- xfree(private);
- return NULL;
- }
-
- private->base.destroy = __glXDRIdrawableDestroy;
- private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
- private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
- private->base.waitGL = __glXDRIdrawableWaitGL;
- private->base.waitX = __glXDRIdrawableWaitX;
-
- if (DRI2CreateDrawable(pDraw)) {
- xfree(private);
- return NULL;
- }
-
- private->driDrawable =
- (*driScreen->dri2->createNewDrawable)(driScreen->driScreen,
- config->driConfig, private);
-
- return &private->base;
-}
-
-static __DRIbuffer *
-dri2GetBuffers(__DRIdrawable *driDrawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *out_count, void *loaderPrivate)
-{
- __GLXDRIdrawable *private = loaderPrivate;
- DRI2BufferPtr *buffers;
- int i;
- int j;
-
- buffers = DRI2GetBuffers(private->base.pDraw,
- width, height, attachments, count, out_count);
- if (*out_count > MAX_DRAWABLE_BUFFERS) {
- *out_count = 0;
- return NULL;
- }
-
- private->width = *width;
- private->height = *height;
-
- /* This assumes the DRI2 buffer attachment tokens matches the
- * __DRIbuffer tokens. */
- j = 0;
- for (i = 0; i < *out_count; i++) {
- /* Do not send the real front buffer of a window to the client.
- */
- if ((private->base.pDraw->type == DRAWABLE_WINDOW)
- && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
- continue;
- }
-
- private->buffers[j].attachment = buffers[i]->attachment;
- private->buffers[j].name = buffers[i]->name;
- private->buffers[j].pitch = buffers[i]->pitch;
- private->buffers[j].cpp = buffers[i]->cpp;
- private->buffers[j].flags = buffers[i]->flags;
- j++;
- }
-
- *out_count = j;
- return private->buffers;
-}
-
-static __DRIbuffer *
-dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *out_count, void *loaderPrivate)
-{
- __GLXDRIdrawable *private = loaderPrivate;
- DRI2BufferPtr *buffers;
- int i;
- int j = 0;
-
- buffers = DRI2GetBuffersWithFormat(private->base.pDraw,
- width, height, attachments, count,
- out_count);
- if (*out_count > MAX_DRAWABLE_BUFFERS) {
- *out_count = 0;
- return NULL;
- }
-
- private->width = *width;
- private->height = *height;
-
- /* This assumes the DRI2 buffer attachment tokens matches the
- * __DRIbuffer tokens. */
- for (i = 0; i < *out_count; i++) {
- /* Do not send the real front buffer of a window to the client.
- */
- if ((private->base.pDraw->type == DRAWABLE_WINDOW)
- && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
- continue;
- }
-
- private->buffers[j].attachment = buffers[i]->attachment;
- private->buffers[j].name = buffers[i]->name;
- private->buffers[j].pitch = buffers[i]->pitch;
- private->buffers[j].cpp = buffers[i]->cpp;
- private->buffers[j].flags = buffers[i]->flags;
- j++;
- }
-
- *out_count = j;
- return private->buffers;
-}
-
-static void
-dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
-{
- (void) driDrawable;
- __glXDRIdrawableWaitGL((__GLXdrawable *) loaderPrivate);
-}
-
-static const __DRIdri2LoaderExtension loaderExtension = {
- { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
- dri2GetBuffers,
- dri2FlushFrontBuffer,
- dri2GetBuffersWithFormat,
-};
-
-static const __DRIextension *loader_extensions[] = {
- &systemTimeExtension.base,
- &loaderExtension.base,
- NULL
-};
-
-static const char dri_driver_path[] = DRI_DRIVER_PATH;
-
-static Bool
-glxDRIEnterVT (int index, int flags)
-{
- __GLXDRIscreen *screen = (__GLXDRIscreen *)
- glxGetScreen(screenInfo.screens[index]);
-
- LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
-
- if (!(*screen->enterVT) (index, flags))
- return FALSE;
-
- glxResumeClients();
-
- return TRUE;
-}
-
-static void
-glxDRILeaveVT (int index, int flags)
-{
- __GLXDRIscreen *screen = (__GLXDRIscreen *)
- glxGetScreen(screenInfo.screens[index]);
-
- LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
-
- glxSuspendClients();
-
- return (*screen->leaveVT) (index, flags);
-}
-
-static void
-initializeExtensions(__GLXDRIscreen *screen)
-{
- ScreenPtr pScreen = screen->base.pScreen;
- const __DRIextension **extensions;
- int i;
-
- extensions = screen->core->getExtensions(screen->driScreen);
-
- __glXEnableExtension(screen->glx_enable_bits,
- "GLX_MESA_copy_sub_buffer");
- LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
-
- __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
- LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
-
- if (DRI2HasSwapControl(pScreen)) {
- __glXEnableExtension(screen->glx_enable_bits,
- "GLX_SGI_swap_control");
- __glXEnableExtension(screen->glx_enable_bits,
- "GLX_MESA_swap_control");
- LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
- }
-
- for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_READ_DRAWABLE
- if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
- __glXEnableExtension(screen->glx_enable_bits,
- "GLX_SGI_make_current_read");
-
- LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
- }
-#endif
-
-#ifdef __DRI_TEX_BUFFER
- if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
- screen->texBuffer =
- (const __DRItexBufferExtension *) extensions[i];
- /* GLX_EXT_texture_from_pixmap is always enabled. */
- LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
- }
-#endif
-
-#ifdef __DRI2_FLUSH
- if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
- extensions[i]->version >= __DRI2_FLUSH_VERSION) {
- screen->flush = (__DRI2flushExtension *) extensions[i];
- }
-#endif
-
- /* Ignore unknown extensions */
- }
-}
-
-static __GLXscreen *
-__glXDRIscreenProbe(ScreenPtr pScreen)
-{
- const char *driverName, *deviceName;
- __GLXDRIscreen *screen;
- char filename[128];
- size_t buffer_size;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- const __DRIextension **extensions;
- const __DRIconfig **driConfigs;
- int i;
-
- screen = xcalloc(1, sizeof *screen);
- if (screen == NULL)
- return NULL;
-
- if (!xf86LoaderCheckSymbol("DRI2Connect") ||
- !DRI2Connect(pScreen, DRI2DriverDRI,
- &screen->fd, &driverName, &deviceName)) {
- LogMessage(X_INFO,
- "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
- return NULL;
- }
-
- screen->base.destroy = __glXDRIscreenDestroy;
- screen->base.createContext = __glXDRIscreenCreateContext;
- screen->base.createDrawable = __glXDRIscreenCreateDrawable;
- screen->base.swapInterval = __glXDRIdrawableSwapInterval;
- screen->base.pScreen = pScreen;
-
- __glXInitExtensionEnableBits(screen->glx_enable_bits);
-
- snprintf(filename, sizeof filename,
- "%s/%s_dri.so", dri_driver_path, driverName);
-
- screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
- if (screen->driver == NULL) {
- LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
- filename, dlerror());
- goto handle_error;
- }
-
- extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
- if (extensions == NULL) {
- LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
- driverName, dlerror());
- goto handle_error;
- }
-
- for (i = 0; extensions[i]; i++) {
- if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
- extensions[i]->version >= __DRI_CORE_VERSION) {
- screen->core = (const __DRIcoreExtension *) extensions[i];
- }
- if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
- extensions[i]->version >= __DRI_DRI2_VERSION) {
- screen->dri2 = (const __DRIdri2Extension *) extensions[i];
- }
- }
-
- if (screen->core == NULL || screen->dri2 == NULL) {
- LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
- driverName);
- goto handle_error;
- }
-
- screen->driScreen =
- (*screen->dri2->createNewScreen)(pScreen->myNum,
- screen->fd,
- loader_extensions,
- &driConfigs,
- screen);
-
- if (screen->driScreen == NULL) {
- LogMessage(X_ERROR,
- "AIGLX error: Calling driver entry point failed\n");
- goto handle_error;
- }
-
- initializeExtensions(screen);
-
- screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs,
- GLX_WINDOW_BIT |
- GLX_PIXMAP_BIT |
- GLX_PBUFFER_BIT);
-
- __glXScreenInit(&screen->base, pScreen);
-
- /* The first call simply determines the length of the extension string.
- * This allows us to allocate some memory to hold the extension string,
- * but it requires that we call __glXGetExtensionString a second time.
- */
- buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
- if (buffer_size > 0) {
- if (screen->base.GLXextensions != NULL) {
- xfree(screen->base.GLXextensions);
- }
-
- screen->base.GLXextensions = xnfalloc(buffer_size);
- (void) __glXGetExtensionString(screen->glx_enable_bits,
- screen->base.GLXextensions);
- }
-
- /* We're going to assume (perhaps incorrectly?) that all DRI2-enabled
- * drivers support the required extensions for GLX 1.4. The extensions
- * we're assuming are:
- *
- * - GLX_SGI_make_current_read (1.3)
- * - GLX_SGIX_fbconfig (1.3)
- * - GLX_SGIX_pbuffer (1.3)
- * - GLX_ARB_multisample (1.4)
- */
- screen->base.GLXmajor = 1;
- screen->base.GLXminor = 4;
-
- screen->enterVT = pScrn->EnterVT;
- pScrn->EnterVT = glxDRIEnterVT;
- screen->leaveVT = pScrn->LeaveVT;
- pScrn->LeaveVT = glxDRILeaveVT;
-
- LogMessage(X_INFO,
- "AIGLX: Loaded and initialized %s\n", filename);
-
- return &screen->base;
-
- handle_error:
- if (screen->driver)
- dlclose(screen->driver);
-
- xfree(screen);
-
- LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
-
- return NULL;
-}
-
-_X_EXPORT __GLXprovider __glXDRI2Provider = {
- __glXDRIscreenProbe,
- "DRI2",
- NULL
-};
+/*
+ * Copyright © 2007 Red Hat, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat,
+ * Inc not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RED HAT, INC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <dlfcn.h>
+
+#include <drm.h>
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include <GL/glxtokens.h>
+
+#include <windowstr.h>
+#include <os.h>
+
+#define _XF86DRI_SERVER_
+#include <xf86drm.h>
+#include <xf86.h>
+#include <dri2.h>
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxdricommon.h"
+
+#include "g_disptab.h"
+#include "glapitable.h"
+#include "glapi.h"
+#include "glthread.h"
+#include "dispatch.h"
+#include "extension_string.h"
+
+typedef struct __GLXDRIscreen __GLXDRIscreen;
+typedef struct __GLXDRIcontext __GLXDRIcontext;
+typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+
+struct __GLXDRIscreen {
+ __GLXscreen base;
+ __DRIscreen *driScreen;
+ void *driver;
+ int fd;
+
+ xf86EnterVTProc *enterVT;
+ xf86LeaveVTProc *leaveVT;
+
+ const __DRIcoreExtension *core;
+ const __DRIdri2Extension *dri2;
+ const __DRI2flushExtension *flush;
+ const __DRIcopySubBufferExtension *copySubBuffer;
+ const __DRIswapControlExtension *swapControl;
+ const __DRItexBufferExtension *texBuffer;
+
+ unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+};
+
+struct __GLXDRIcontext {
+ __GLXcontext base;
+ __DRIcontext *driContext;
+};
+
+#define MAX_DRAWABLE_BUFFERS 5
+
+struct __GLXDRIdrawable {
+ __GLXdrawable base;
+ __DRIdrawable *driDrawable;
+ __GLXDRIscreen *screen;
+
+ /* Dimensions as last reported by DRI2GetBuffers. */
+ int width;
+ int height;
+ __DRIbuffer buffers[MAX_DRAWABLE_BUFFERS];
+ int count;
+};
+
+static void
+__glXDRIdrawableDestroy(__GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+ const __DRIcoreExtension *core = private->screen->core;
+
+ (*core->destroyDrawable)(private->driDrawable);
+
+ __glXDrawableRelease(drawable);
+
+ xfree(private);
+}
+
+static void
+__glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
+ int x, int y, int w, int h)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = x;
+ box.y1 = private->height - y - h;
+ box.x2 = x + w;
+ box.y2 = private->height - y;
+ REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
+
+ DRI2CopyRegion(drawable->pDraw, &region,
+ DRI2BufferFrontLeft, DRI2BufferBackLeft);
+}
+
+static void
+__glXDRIdrawableWaitX(__GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = private->width;
+ box.y2 = private->height;
+ REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
+
+ DRI2CopyRegion(drawable->pDraw, &region,
+ DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+}
+
+static void
+__glXDRIdrawableWaitGL(__GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = private->width;
+ box.y2 = private->height;
+ REGION_INIT(drawable->pDraw->pScreen, &region, &box, 0);
+
+ DRI2CopyRegion(drawable->pDraw, &region,
+ DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+}
+
+static void
+__glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust,
+ CARD64 msc, CARD64 sbc)
+{
+ __GLXdrawable *drawable = data;
+ xGLXBufferSwapComplete wire;
+
+ if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
+ return;
+
+ wire.type = __glXEventBase + GLX_BufferSwapComplete;
+ switch (type) {
+ case DRI2_EXCHANGE_COMPLETE:
+ wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL;
+ break;
+ case DRI2_BLIT_COMPLETE:
+ wire.event_type = GLX_BLIT_COMPLETE_INTEL;
+ break;
+ case DRI2_FLIP_COMPLETE:
+ wire.event_type = GLX_FLIP_COMPLETE_INTEL;
+ break;
+ default:
+ /* unknown swap completion type */
+ break;
+ }
+ wire.sequenceNumber = client->sequence;
+ wire.drawable = drawable->drawId;
+ wire.ust_hi = ust >> 32;
+ wire.ust_lo = ust & 0xffffffff;
+ wire.msc_hi = msc >> 32;
+ wire.msc_lo = msc & 0xffffffff;
+ wire.sbc_hi = sbc >> 32;
+ wire.sbc_lo = sbc & 0xffffffff;
+
+ WriteEventsToClient(client, 1, (xEvent *) &wire);
+}
+
+/*
+ * Copy or flip back to front, honoring the swap interval if possible.
+ *
+ * If the kernel supports it, we request an event for the frame when the
+ * swap should happen, then perform the copy when we receive it.
+ */
+static GLboolean
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
+ __GLXDRIscreen *screen = priv->screen;
+ CARD64 unused;
+
+#if __DRI2_FLUSH_VERSION >= 3
+ if (screen->flush) {
+ (*screen->flush->flush)(priv->driDrawable);
+ (*screen->flush->invalidate)(priv->driDrawable);
+ }
+#else
+ if (screen->flush)
+ (*screen->flush->flushInvalidate)(priv->driDrawable);
+#endif
+
+ if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused,
+ __glXdriSwapEvent, drawable->pDraw) != Success)
+ return FALSE;
+
+ return TRUE;
+}
+
+static int
+__glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
+{
+ if (interval <= 0) /* || interval > BIGNUM? */
+ return GLX_BAD_VALUE;
+
+ DRI2SwapInterval(drawable->pDraw, interval);
+
+ return 0;
+}
+
+static void
+__glXDRIcontextDestroy(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ (*screen->core->destroyContext)(context->driContext);
+ __glXContextDestroy(&context->base);
+ xfree(context);
+}
+
+static int
+__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->bindContext)(context->driContext,
+ draw->driDrawable,
+ read->driDrawable);
+}
+
+static int
+__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->unbindContext)(context->driContext);
+}
+
+static int
+__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
+ unsigned long mask)
+{
+ __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
+ __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
+
+ return (*screen->core->copyContext)(dst->driContext,
+ src->driContext, mask);
+}
+
+static int
+__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->bindContext)(context->driContext,
+ draw->driDrawable,
+ read->driDrawable);
+}
+
+static Bool
+__glXDRIcontextWait(__GLXcontext *baseContext,
+ __GLXclientState *cl, int *error)
+{
+ if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) {
+ *error = cl->client->noClientException;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#ifdef __DRI_TEX_BUFFER
+
+static int
+__glXDRIbindTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *glxPixmap)
+{
+ __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
+ const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+
+ if (texBuffer == NULL)
+ return Success;
+
+#if __DRI_TEX_BUFFER_VERSION >= 2
+ if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
+ (*texBuffer->setTexBuffer2)(context->driContext,
+ glxPixmap->target,
+ glxPixmap->format,
+ drawable->driDrawable);
+ } else
+#endif
+ {
+ texBuffer->setTexBuffer(context->driContext,
+ glxPixmap->target,
+ drawable->driDrawable);
+ }
+
+ return Success;
+}
+
+static int
+__glXDRIreleaseTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ /* FIXME: Just unbind the texture? */
+ return Success;
+}
+
+#else
+
+static int
+__glXDRIbindTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *glxPixmap)
+{
+ return Success;
+}
+
+static int
+__glXDRIreleaseTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ return Success;
+}
+
+#endif
+
+static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
+ __glXDRIbindTexImage,
+ __glXDRIreleaseTexImage
+};
+
+static void
+__glXDRIscreenDestroy(__GLXscreen *baseScreen)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+
+ (*screen->core->destroyScreen)(screen->driScreen);
+
+ dlclose(screen->driver);
+
+ __glXScreenDestroy(baseScreen);
+
+ xfree(screen);
+}
+
+static __GLXcontext *
+__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
+ __GLXconfig *glxConfig,
+ __GLXcontext *baseShareContext)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+ __GLXDRIcontext *context, *shareContext;
+ __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+ __DRIcontext *driShare;
+
+ shareContext = (__GLXDRIcontext *) baseShareContext;
+ if (shareContext)
+ driShare = shareContext->driContext;
+ else
+ driShare = NULL;
+
+ context = xcalloc(1, sizeof *context);
+ if (context == NULL)
+ return NULL;
+
+ context->base.destroy = __glXDRIcontextDestroy;
+ context->base.makeCurrent = __glXDRIcontextMakeCurrent;
+ context->base.loseCurrent = __glXDRIcontextLoseCurrent;
+ context->base.copy = __glXDRIcontextCopy;
+ context->base.forceCurrent = __glXDRIcontextForceCurrent;
+ context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+ context->base.wait = __glXDRIcontextWait;
+
+ context->driContext =
+ (*screen->dri2->createNewContext)(screen->driScreen,
+ config->driConfig,
+ driShare, context);
+ if (context->driContext == NULL) {
+ xfree(context);
+ return NULL;
+ }
+
+ return &context->base;
+}
+
+static __GLXdrawable *
+__glXDRIscreenCreateDrawable(ClientPtr client,
+ __GLXscreen *screen,
+ DrawablePtr pDraw,
+ XID drawId,
+ int type,
+ XID glxDrawId,
+ __GLXconfig *glxConfig)
+{
+ __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
+ __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+ __GLXDRIdrawable *private;
+
+ private = xcalloc(1, sizeof *private);
+ if (private == NULL)
+ return NULL;
+
+ private->screen = driScreen;
+ if (!__glXDrawableInit(&private->base, screen,
+ pDraw, type, glxDrawId, glxConfig)) {
+ xfree(private);
+ return NULL;
+ }
+
+ private->base.destroy = __glXDRIdrawableDestroy;
+ private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
+ private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+ private->base.waitGL = __glXDRIdrawableWaitGL;
+ private->base.waitX = __glXDRIdrawableWaitX;
+
+ if (DRI2CreateDrawable(client, pDraw, drawId)) {
+ xfree(private);
+ return NULL;
+ }
+
+ private->driDrawable =
+ (*driScreen->dri2->createNewDrawable)(driScreen->driScreen,
+ config->driConfig, private);
+
+ return &private->base;
+}
+
+static __DRIbuffer *
+dri2GetBuffers(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
+{
+ __GLXDRIdrawable *private = loaderPrivate;
+ DRI2BufferPtr *buffers;
+ int i;
+ int j;
+
+ buffers = DRI2GetBuffers(private->base.pDraw,
+ width, height, attachments, count, out_count);
+ if (*out_count > MAX_DRAWABLE_BUFFERS) {
+ *out_count = 0;
+ return NULL;
+ }
+
+ private->width = *width;
+ private->height = *height;
+
+ /* This assumes the DRI2 buffer attachment tokens matches the
+ * __DRIbuffer tokens. */
+ j = 0;
+ for (i = 0; i < *out_count; i++) {
+ /* Do not send the real front buffer of a window to the client.
+ */
+ if ((private->base.pDraw->type == DRAWABLE_WINDOW)
+ && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
+ continue;
+ }
+
+ private->buffers[j].attachment = buffers[i]->attachment;
+ private->buffers[j].name = buffers[i]->name;
+ private->buffers[j].pitch = buffers[i]->pitch;
+ private->buffers[j].cpp = buffers[i]->cpp;
+ private->buffers[j].flags = buffers[i]->flags;
+ j++;
+ }
+
+ *out_count = j;
+ return private->buffers;
+}
+
+static __DRIbuffer *
+dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
+{
+ __GLXDRIdrawable *private = loaderPrivate;
+ DRI2BufferPtr *buffers;
+ int i;
+ int j = 0;
+
+ buffers = DRI2GetBuffersWithFormat(private->base.pDraw,
+ width, height, attachments, count,
+ out_count);
+ if (*out_count > MAX_DRAWABLE_BUFFERS) {
+ *out_count = 0;
+ return NULL;
+ }
+
+ private->width = *width;
+ private->height = *height;
+
+ /* This assumes the DRI2 buffer attachment tokens matches the
+ * __DRIbuffer tokens. */
+ for (i = 0; i < *out_count; i++) {
+ /* Do not send the real front buffer of a window to the client.
+ */
+ if ((private->base.pDraw->type == DRAWABLE_WINDOW)
+ && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
+ continue;
+ }
+
+ private->buffers[j].attachment = buffers[i]->attachment;
+ private->buffers[j].name = buffers[i]->name;
+ private->buffers[j].pitch = buffers[i]->pitch;
+ private->buffers[j].cpp = buffers[i]->cpp;
+ private->buffers[j].flags = buffers[i]->flags;
+ j++;
+ }
+
+ *out_count = j;
+ return private->buffers;
+}
+
+static void
+dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
+{
+ (void) driDrawable;
+ __glXDRIdrawableWaitGL((__GLXdrawable *) loaderPrivate);
+}
+
+static const __DRIdri2LoaderExtension loaderExtension = {
+ { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
+ dri2GetBuffers,
+ dri2FlushFrontBuffer,
+ dri2GetBuffersWithFormat,
+};
+
+static const __DRIextension *loader_extensions[] = {
+ &systemTimeExtension.base,
+ &loaderExtension.base,
+ NULL
+};
+
+static const char dri_driver_path[] = DRI_DRIVER_PATH;
+
+static Bool
+glxDRIEnterVT (int index, int flags)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[index]);
+
+ LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
+
+ if (!(*screen->enterVT) (index, flags))
+ return FALSE;
+
+ glxResumeClients();
+
+ return TRUE;
+}
+
+static void
+glxDRILeaveVT (int index, int flags)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[index]);
+
+ LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
+
+ glxSuspendClients();
+
+ return (*screen->leaveVT) (index, flags);
+}
+
+static void
+initializeExtensions(__GLXDRIscreen *screen)
+{
+ ScreenPtr pScreen = screen->base.pScreen;
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = screen->core->getExtensions(screen->driScreen);
+
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_MESA_copy_sub_buffer");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
+
+ if (DRI2HasSwapControl(pScreen)) {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_SGI_swap_control");
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_MESA_swap_control");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+ }
+
+ for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_READ_DRAWABLE
+ if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_SGI_make_current_read");
+
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
+ }
+#endif
+
+#ifdef __DRI_TEX_BUFFER
+ if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
+ screen->texBuffer =
+ (const __DRItexBufferExtension *) extensions[i];
+ /* GLX_EXT_texture_from_pixmap is always enabled. */
+ LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
+ }
+#endif
+
+#ifdef __DRI2_FLUSH
+ if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
+ extensions[i]->version >= 3) {
+ screen->flush = (__DRI2flushExtension *) extensions[i];
+ }
+#endif
+
+ /* Ignore unknown extensions */
+ }
+}
+
+static __GLXscreen *
+__glXDRIscreenProbe(ScreenPtr pScreen)
+{
+ const char *driverName, *deviceName;
+ __GLXDRIscreen *screen;
+ char filename[128];
+ size_t buffer_size;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ const __DRIextension **extensions;
+ const __DRIconfig **driConfigs;
+ int i;
+
+ screen = xcalloc(1, sizeof *screen);
+ if (screen == NULL)
+ return NULL;
+
+ if (!xf86LoaderCheckSymbol("DRI2Connect") ||
+ !DRI2Connect(pScreen, DRI2DriverDRI,
+ &screen->fd, &driverName, &deviceName)) {
+ LogMessage(X_INFO,
+ "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
+ return NULL;
+ }
+
+ screen->base.destroy = __glXDRIscreenDestroy;
+ screen->base.createContext = __glXDRIscreenCreateContext;
+ screen->base.createDrawable = __glXDRIscreenCreateDrawable;
+ screen->base.swapInterval = __glXDRIdrawableSwapInterval;
+ screen->base.pScreen = pScreen;
+
+ __glXInitExtensionEnableBits(screen->glx_enable_bits);
+
+ snprintf(filename, sizeof filename,
+ "%s/%s_dri.so", dri_driver_path, driverName);
+
+ screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+ if (screen->driver == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+ filename, dlerror());
+ goto handle_error;
+ }
+
+ extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
+ driverName, dlerror());
+ goto handle_error;
+ }
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
+ extensions[i]->version >= 1) {
+ screen->core = (const __DRIcoreExtension *) extensions[i];
+ }
+ if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
+ extensions[i]->version >= 1) {
+ screen->dri2 = (const __DRIdri2Extension *) extensions[i];
+ }
+ }
+
+ if (screen->core == NULL || screen->dri2 == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
+ driverName);
+ goto handle_error;
+ }
+
+ screen->driScreen =
+ (*screen->dri2->createNewScreen)(pScreen->myNum,
+ screen->fd,
+ loader_extensions,
+ &driConfigs,
+ screen);
+
+ if (screen->driScreen == NULL) {
+ LogMessage(X_ERROR,
+ "AIGLX error: Calling driver entry point failed\n");
+ goto handle_error;
+ }
+
+ initializeExtensions(screen);
+
+ screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs,
+ GLX_WINDOW_BIT |
+ GLX_PIXMAP_BIT |
+ GLX_PBUFFER_BIT);
+
+ __glXScreenInit(&screen->base, pScreen);
+
+ /* The first call simply determines the length of the extension string.
+ * This allows us to allocate some memory to hold the extension string,
+ * but it requires that we call __glXGetExtensionString a second time.
+ */
+ buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+ if (buffer_size > 0) {
+ if (screen->base.GLXextensions != NULL) {
+ xfree(screen->base.GLXextensions);
+ }
+
+ screen->base.GLXextensions = xnfalloc(buffer_size);
+ (void) __glXGetExtensionString(screen->glx_enable_bits,
+ screen->base.GLXextensions);
+ }
+
+ /* We're going to assume (perhaps incorrectly?) that all DRI2-enabled
+ * drivers support the required extensions for GLX 1.4. The extensions
+ * we're assuming are:
+ *
+ * - GLX_SGI_make_current_read (1.3)
+ * - GLX_SGIX_fbconfig (1.3)
+ * - GLX_SGIX_pbuffer (1.3)
+ * - GLX_ARB_multisample (1.4)
+ */
+ screen->base.GLXmajor = 1;
+ screen->base.GLXminor = 4;
+
+ screen->enterVT = pScrn->EnterVT;
+ pScrn->EnterVT = glxDRIEnterVT;
+ screen->leaveVT = pScrn->LeaveVT;
+ pScrn->LeaveVT = glxDRILeaveVT;
+
+ LogMessage(X_INFO,
+ "AIGLX: Loaded and initialized %s\n", filename);
+
+ return &screen->base;
+
+ handle_error:
+ if (screen->driver)
+ dlclose(screen->driver);
+
+ xfree(screen);
+
+ LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
+
+ return NULL;
+}
+
+_X_EXPORT __GLXprovider __glXDRI2Provider = {
+ __glXDRIscreenProbe,
+ "DRI2",
+ NULL
+};
diff --git a/xorg-server/glx/glxdriswrast.c b/xorg-server/glx/glxdriswrast.c
index cfac16133..3852b5243 100644
--- a/xorg-server/glx/glxdriswrast.c
+++ b/xorg-server/glx/glxdriswrast.c
@@ -313,10 +313,12 @@ glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val)
}
static __GLXdrawable *
-__glXDRIscreenCreateDrawable(__GLXscreen *screen,
+__glXDRIscreenCreateDrawable(ClientPtr client,
+ __GLXscreen *screen,
DrawablePtr pDraw,
- int type,
XID drawId,
+ int type,
+ XID glxDrawId,
__GLXconfig *glxConfig)
{
__GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
@@ -331,7 +333,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
private->screen = driScreen;
if (!__glXDrawableInit(&private->base, screen,
- pDraw, type, drawId, glxConfig)) {
+ pDraw, type, glxDrawId, glxConfig)) {
xfree(private);
return NULL;
}
diff --git a/xorg-server/glx/glxscreens.h b/xorg-server/glx/glxscreens.h
index d52099fc2..335d471b3 100644
--- a/xorg-server/glx/glxscreens.h
+++ b/xorg-server/glx/glxscreens.h
@@ -1,182 +1,184 @@
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _GLX_screens_h_
-#define _GLX_screens_h_
-
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-typedef struct {
- void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
- void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
- int (* destroyHyperpipeConfigFunc)(int, int);
- void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
-} __GLXHyperpipeExtensionFuncs;
-
-typedef struct {
- int (* bindSwapBarrierFunc)(int, XID, int);
- int (* queryMaxSwapBarriersFunc)(int);
-} __GLXSwapBarrierExtensionFuncs;
-
-void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
-void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
-
-typedef struct __GLXconfig __GLXconfig;
-struct __GLXconfig {
- __GLXconfig *next;
- GLuint doubleBufferMode;
- GLuint stereoMode;
-
- GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
- GLuint redMask, greenMask, blueMask, alphaMask;
- GLint rgbBits; /* total bits for rgb */
- GLint indexBits; /* total bits for colorindex */
-
- GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
- GLint depthBits;
- GLint stencilBits;
-
- GLint numAuxBuffers;
-
- GLint level;
-
- GLint pixmapMode;
-
- /* GLX */
- GLint visualID;
- GLint visualType; /**< One of the GLX X visual types. (i.e.,
- * \c GLX_TRUE_COLOR, etc.)
- */
-
- /* EXT_visual_rating / GLX 1.2 */
- GLint visualRating;
-
- /* EXT_visual_info / GLX 1.2 */
- GLint transparentPixel;
- /* colors are floats scaled to ints */
- GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
- GLint transparentIndex;
-
- /* ARB_multisample / SGIS_multisample */
- GLint sampleBuffers;
- GLint samples;
-
- /* SGIX_fbconfig / GLX 1.3 */
- GLint drawableType;
- GLint renderType;
- GLint xRenderable;
- GLint fbconfigID;
-
- /* SGIX_pbuffer / GLX 1.3 */
- GLint maxPbufferWidth;
- GLint maxPbufferHeight;
- GLint maxPbufferPixels;
- GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
- GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
-
- /* SGIX_visual_select_group */
- GLint visualSelectGroup;
-
- /* OML_swap_method */
- GLint swapMethod;
-
- GLint screen;
-
- /* EXT_texture_from_pixmap */
- GLint bindToTextureRgb;
- GLint bindToTextureRgba;
- GLint bindToMipmapTexture;
- GLint bindToTextureTargets;
- GLint yInverted;
-};
-
-GLint glxConvertToXVisualType(int visualType);
-
-/*
-** Screen dependent data. These methods are the interface between the DIX
-** and DDX layers of the GLX server extension. The methods provide an
-** interface for context management on a screen.
-*/
-typedef struct __GLXscreen __GLXscreen;
-struct __GLXscreen {
- void (*destroy) (__GLXscreen *screen);
-
- __GLXcontext *(*createContext) (__GLXscreen *screen,
- __GLXconfig *modes,
- __GLXcontext *shareContext);
-
- __GLXdrawable *(*createDrawable)(__GLXscreen *context,
- DrawablePtr pDraw,
- int type,
- XID drawId,
- __GLXconfig *modes);
- int (*swapInterval) (__GLXdrawable *drawable,
- int interval);
-
- __GLXHyperpipeExtensionFuncs *hyperpipeFuncs;
- __GLXSwapBarrierExtensionFuncs *swapBarrierFuncs;
-
- ScreenPtr pScreen;
-
- /* Linked list of valid fbconfigs for this screen. */
- __GLXconfig *fbconfigs;
- int numFBConfigs;
-
- /* Subset of fbconfigs that are exposed as GLX visuals. */
- __GLXconfig **visuals;
- GLint numVisuals;
-
- char *GLextensions;
-
- char *GLXvendor;
- char *GLXversion;
- char *GLXextensions;
-
- /**
- * \name GLX version supported by this screen.
- *
- * Since the GLX version advertised by the server is for the whole server,
- * the GLX protocol code uses the minimum version supported on all screens.
- */
- /*@{*/
- unsigned GLXmajor;
- unsigned GLXminor;
- /*@}*/
-
- Bool (*CloseScreen)(int index, ScreenPtr pScreen);
-};
-
-
-void __glXScreenInit(__GLXscreen *screen, ScreenPtr pScreen);
-void __glXScreenDestroy(__GLXscreen *screen);
-
-#endif /* !__GLX_screens_h__ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_screens_h_
+#define _GLX_screens_h_
+
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+typedef struct {
+ void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
+ void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
+ int (* destroyHyperpipeConfigFunc)(int, int);
+ void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
+} __GLXHyperpipeExtensionFuncs;
+
+typedef struct {
+ int (* bindSwapBarrierFunc)(int, XID, int);
+ int (* queryMaxSwapBarriersFunc)(int);
+} __GLXSwapBarrierExtensionFuncs;
+
+void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
+void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
+
+typedef struct __GLXconfig __GLXconfig;
+struct __GLXconfig {
+ __GLXconfig *next;
+ GLuint doubleBufferMode;
+ GLuint stereoMode;
+
+ GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
+ GLuint redMask, greenMask, blueMask, alphaMask;
+ GLint rgbBits; /* total bits for rgb */
+ GLint indexBits; /* total bits for colorindex */
+
+ GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
+ GLint depthBits;
+ GLint stencilBits;
+
+ GLint numAuxBuffers;
+
+ GLint level;
+
+ GLint pixmapMode;
+
+ /* GLX */
+ GLint visualID;
+ GLint visualType; /**< One of the GLX X visual types. (i.e.,
+ * \c GLX_TRUE_COLOR, etc.)
+ */
+
+ /* EXT_visual_rating / GLX 1.2 */
+ GLint visualRating;
+
+ /* EXT_visual_info / GLX 1.2 */
+ GLint transparentPixel;
+ /* colors are floats scaled to ints */
+ GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
+ GLint transparentIndex;
+
+ /* ARB_multisample / SGIS_multisample */
+ GLint sampleBuffers;
+ GLint samples;
+
+ /* SGIX_fbconfig / GLX 1.3 */
+ GLint drawableType;
+ GLint renderType;
+ GLint xRenderable;
+ GLint fbconfigID;
+
+ /* SGIX_pbuffer / GLX 1.3 */
+ GLint maxPbufferWidth;
+ GLint maxPbufferHeight;
+ GLint maxPbufferPixels;
+ GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
+ GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
+
+ /* SGIX_visual_select_group */
+ GLint visualSelectGroup;
+
+ /* OML_swap_method */
+ GLint swapMethod;
+
+ GLint screen;
+
+ /* EXT_texture_from_pixmap */
+ GLint bindToTextureRgb;
+ GLint bindToTextureRgba;
+ GLint bindToMipmapTexture;
+ GLint bindToTextureTargets;
+ GLint yInverted;
+};
+
+GLint glxConvertToXVisualType(int visualType);
+
+/*
+** Screen dependent data. These methods are the interface between the DIX
+** and DDX layers of the GLX server extension. The methods provide an
+** interface for context management on a screen.
+*/
+typedef struct __GLXscreen __GLXscreen;
+struct __GLXscreen {
+ void (*destroy) (__GLXscreen *screen);
+
+ __GLXcontext *(*createContext) (__GLXscreen *screen,
+ __GLXconfig *modes,
+ __GLXcontext *shareContext);
+
+ __GLXdrawable *(*createDrawable)(ClientPtr client,
+ __GLXscreen *context,
+ DrawablePtr pDraw,
+ XID drawId,
+ int type,
+ XID glxDrawId,
+ __GLXconfig *modes);
+ int (*swapInterval) (__GLXdrawable *drawable,
+ int interval);
+
+ __GLXHyperpipeExtensionFuncs *hyperpipeFuncs;
+ __GLXSwapBarrierExtensionFuncs *swapBarrierFuncs;
+
+ ScreenPtr pScreen;
+
+ /* Linked list of valid fbconfigs for this screen. */
+ __GLXconfig *fbconfigs;
+ int numFBConfigs;
+
+ /* Subset of fbconfigs that are exposed as GLX visuals. */
+ __GLXconfig **visuals;
+ GLint numVisuals;
+
+ char *GLextensions;
+
+ char *GLXvendor;
+ char *GLXversion;
+ char *GLXextensions;
+
+ /**
+ * \name GLX version supported by this screen.
+ *
+ * Since the GLX version advertised by the server is for the whole server,
+ * the GLX protocol code uses the minimum version supported on all screens.
+ */
+ /*@{*/
+ unsigned GLXmajor;
+ unsigned GLXminor;
+ /*@}*/
+
+ Bool (*CloseScreen)(int index, ScreenPtr pScreen);
+};
+
+
+void __glXScreenInit(__GLXscreen *screen, ScreenPtr pScreen);
+void __glXScreenDestroy(__GLXscreen *screen);
+
+#endif /* !__GLX_screens_h__ */