summaryrefslogtreecommitdiff
path: root/xserver/GL/glx
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2008-06-15 00:17:34 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2008-06-15 00:17:34 +0000
commit86fc487fbc0e5e6f7146a43099dc7ce1791c84f0 (patch)
tree86479ce8d7fc54c515b1aac90f960401587caef0 /xserver/GL/glx
parentf629cb662c6469d23587f9dffc2352a8b6505b7b (diff)
Update to xserver 1.4.2. Tested by landry@, ckuethe@, jsing@ mbalmer@.
Diffstat (limited to 'xserver/GL/glx')
-rw-r--r--xserver/GL/glx/glxdri.c338
1 files changed, 246 insertions, 92 deletions
diff --git a/xserver/GL/glx/glxdri.c b/xserver/GL/glx/glxdri.c
index 170662c7e..09abca3f9 100644
--- a/xserver/GL/glx/glxdri.c
+++ b/xserver/GL/glx/glxdri.c
@@ -76,6 +76,11 @@ struct __GLXDRIscreen {
xf86EnterVTProc *enterVT;
xf86LeaveVTProc *leaveVT;
+ DRITexOffsetStartProcPtr texOffsetStart;
+ DRITexOffsetFinishProcPtr texOffsetFinish;
+ __GLXpixmap* texOffsetOverride[16];
+ GLuint lastTexOffsetOverride;
+
unsigned char glx_enable_bits[__GLX_EXT_BYTES];
};
@@ -125,30 +130,75 @@ struct __GLXDRIdrawable {
static const char CREATE_NEW_SCREEN_FUNC[] =
"__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION);
-/* The DRI driver entry point version wasn't bumped when the
- * copySubBuffer functionality was added to the DRI drivers, but the
- * functionality is still conditional on the value of the
- * internal_api_version passed to __driCreateNewScreen. However, the
- * screen constructor doesn't fail for a DRI driver that's older than
- * the passed in version number, so there's no way we can know for
- * sure that we can actually use the copySubBuffer functionality. But
- * since the earliest (and at this point only) released mesa version
- * (6.5) that uses the 20050727 entry point does have copySubBuffer,
- * we'll just settle for that. We still have to pass in a higher to
- * the screen constructor to enable the functionality.
- */
-#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314
static void
-__glXDRIleaveServer(void)
+__glXDRIleaveServer(GLboolean rendering)
{
- DRIBlockHandler(NULL, NULL, NULL);
+ int i;
+
+ for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+ __GLXDRIscreen * const screen =
+ (__GLXDRIscreen *) __glXgetActiveScreen(i);
+ GLuint lastOverride = screen->lastTexOffsetOverride;
+
+ if (lastOverride) {
+ __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ int j;
+
+ for (j = 0; j < lastOverride; j++) {
+ __GLXpixmap *pGlxPix = texOffsetOverride[j];
+
+ if (pGlxPix && pGlxPix->texname) {
+ pGlxPix->offset =
+ screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw);
+ }
+ }
+ }
+ }
+
+ DRIBlockHandler(NULL, NULL, NULL);
+
+ for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+ __GLXDRIscreen * const screen =
+ (__GLXDRIscreen *) __glXgetActiveScreen(i);
+ GLuint lastOverride = screen->lastTexOffsetOverride;
+
+ if (lastOverride) {
+ __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ int j;
+
+ for (j = 0; j < lastOverride; j++) {
+ __GLXpixmap *pGlxPix = texOffsetOverride[j];
+
+ if (pGlxPix && pGlxPix->texname) {
+ screen->driScreen.setTexOffset(pGlxPix->pDRICtx,
+ pGlxPix->texname,
+ pGlxPix->offset,
+ pGlxPix->pDraw->depth,
+ ((PixmapPtr)pGlxPix->pDraw)->
+ devKind);
+ }
+ }
+ }
+ }
}
static void
-__glXDRIenterServer(void)
+__glXDRIenterServer(GLboolean rendering)
{
- DRIWakeupHandler(NULL, 0, NULL);
+ int i;
+
+ for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+ __GLXDRIscreen * const screen =
+ (__GLXDRIscreen *) __glXgetActiveScreen(i);
+
+ if (screen->lastTexOffsetOverride) {
+ CALL_Flush(GET_DISPATCH(), ());
+ break;
+ }
+ }
+
+ DRIWakeupHandler(NULL, 0, NULL);
}
/**
@@ -289,19 +339,6 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
&context->driContext);
}
-static int
-glxCountBits(int word)
-{
- int ret = 0;
-
- while (word) {
- ret += (word & 1);
- word >>= 1;
- }
-
- return ret;
-}
-
static void
glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
{
@@ -335,19 +372,68 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
int buffer,
__GLXpixmap *glxPixmap)
{
- RegionPtr pRegion;
+ RegionPtr pRegion = NULL;
PixmapPtr pixmap;
- int bpp;
- GLenum target, format, type;
+ int bpp, override = 0;
+ GLenum format, type;
+ ScreenPtr pScreen = glxPixmap->pScreen;
+ __GLXDRIscreen * const screen =
+ (__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
pixmap = (PixmapPtr) glxPixmap->pDraw;
+
+ if (screen->texOffsetStart && screen->driScreen.setTexOffset) {
+ __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ int i, firstEmpty = 16, texname;
+
+ for (i = 0; i < 16; i++) {
+ if (texOffsetOverride[i] == glxPixmap)
+ goto alreadyin;
+
+ if (firstEmpty == 16 && !texOffsetOverride[i])
+ firstEmpty = i;
+ }
+
+ if (firstEmpty == 16) {
+ ErrorF("%s: Failed to register texture offset override\n", __func__);
+ goto nooverride;
+ }
+
+ if (firstEmpty >= screen->lastTexOffsetOverride)
+ screen->lastTexOffsetOverride = firstEmpty + 1;
+
+ texOffsetOverride[firstEmpty] = glxPixmap;
+
+alreadyin:
+ override = 1;
+
+ glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext;
+
+ CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
+ GL_TEXTURE_BINDING_2D :
+ GL_TEXTURE_BINDING_RECTANGLE_NV,
+ &texname));
+
+ if (texname == glxPixmap->texname)
+ return Success;
+
+ glxPixmap->texname = texname;
+
+ screen->driScreen.setTexOffset(glxPixmap->pDRICtx, texname, 0,
+ pixmap->drawable.depth, pixmap->devKind);
+ }
+nooverride:
+
if (!glxPixmap->pDamage) {
- glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
- TRUE, glxPixmap->pScreen, NULL);
- if (!glxPixmap->pDamage)
- return BadAlloc;
+ if (!override) {
+ glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+ TRUE, pScreen, NULL);
+ if (!glxPixmap->pDamage)
+ return BadAlloc;
+
+ DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
+ }
- DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
pRegion = NULL;
} else {
pRegion = DamageRegion(glxPixmap->pDamage);
@@ -360,30 +446,22 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
bpp = 4;
format = GL_BGRA;
type =
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- GL_UNSIGNED_BYTE;
-#else
- GL_UNSIGNED_INT_8_8_8_8_REV;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ !override ? GL_UNSIGNED_INT_8_8_8_8_REV :
#endif
+ GL_UNSIGNED_BYTE;
} else {
bpp = 2;
format = GL_RGB;
type = GL_UNSIGNED_SHORT_5_6_5;
}
- if (!(glxCountBits(pixmap->drawable.width) == 1 &&
- glxCountBits(pixmap->drawable.height) == 1)
- /* || strstr(CALL_GetString(GL_EXTENSIONS,
- "GL_ARB_texture_non_power_of_two")) */)
- target = GL_TEXTURE_RECTANGLE_ARB;
- else
- target = GL_TEXTURE_2D;
-
CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
pixmap->devKind / bpp) );
+
if (pRegion == NULL)
{
- if (pixmap->drawable.depth == 24)
+ if (!override && pixmap->drawable.depth == 24)
glxFillAlphaChannel(pixmap,
pixmap->drawable.x,
pixmap->drawable.y,
@@ -396,7 +474,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
pixmap->drawable.y) );
CALL_TexImage2D( GET_DISPATCH(),
- (target,
+ (glxPixmap->target,
0,
bpp == 4 ? 4 : 3,
pixmap->drawable.width,
@@ -404,8 +482,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
0,
format,
type,
- pixmap->devPrivate.ptr) );
- } else {
+ override ? NULL : pixmap->devPrivate.ptr) );
+ } else if (!override) {
int i, numRects;
BoxPtr p;
@@ -426,7 +504,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
pixmap->drawable.y + p[i].y1) );
CALL_TexSubImage2D( GET_DISPATCH(),
- (target,
+ (glxPixmap->target,
0,
p[i].x1, p[i].y1,
p[i].x2 - p[i].x1, p[i].y2 - p[i].y1,
@@ -436,7 +514,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
}
}
- DamageEmpty(glxPixmap->pDamage);
+ if (!override)
+ DamageEmpty(glxPixmap->pDamage);
return Success;
}
@@ -446,6 +525,40 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext,
int buffer,
__GLXpixmap *pixmap)
{
+ ScreenPtr pScreen = pixmap->pScreen;
+ __GLXDRIscreen * const screen =
+ (__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
+ GLuint lastOverride = screen->lastTexOffsetOverride;
+
+ if (lastOverride) {
+ __GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
+ int i;
+
+ for (i = 0; i < lastOverride; i++) {
+ if (texOffsetOverride[i] == pixmap) {
+ if (screen->texOffsetFinish)
+ screen->texOffsetFinish((PixmapPtr)pixmap->pDraw);
+
+ texOffsetOverride[i] = NULL;
+
+ if (i + 1 == lastOverride) {
+ lastOverride = 0;
+
+ while (i--) {
+ if (texOffsetOverride[i]) {
+ lastOverride = i + 1;
+ break;
+ }
+ }
+
+ screen->lastTexOffsetOverride = lastOverride;
+
+ break;
+ }
+ }
+ }
+ }
+
return Success;
}
@@ -485,6 +598,9 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
else
sharePrivate = NULL;
+ if (baseShareContext && baseShareContext->isDirect)
+ return NULL;
+
context = xalloc(sizeof *context);
if (context == NULL)
return NULL;
@@ -495,6 +611,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
context->base.loseCurrent = __glXDRIcontextLoseCurrent;
context->base.copy = __glXDRIcontextCopy;
context->base.forceCurrent = __glXDRIcontextForceCurrent;
+ context->base.pScreen = screen->base.pScreen;
context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
@@ -503,6 +620,11 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
0, /* render type */
sharePrivate,
&context->driContext);
+
+ if (!context->driContext.private) {
+ xfree(context);
+ return NULL;
+ }
context->driContext.mode = modes;
@@ -637,9 +759,16 @@ static __DRIscreen *findScreen(__DRInativeDisplay *dpy, int scrn)
static GLboolean windowExists(__DRInativeDisplay *dpy, __DRIid draw)
{
- WindowPtr pWin = (WindowPtr) LookupIDByType(draw, RT_WINDOW);
-
- return pWin == NULL ? GL_FALSE : GL_TRUE;
+ DrawablePtr pDrawable = (DrawablePtr) LookupIDByType(draw, RT_WINDOW);
+ int unused;
+ drm_clip_rect_t *pRects;
+
+ return pDrawable ? DRIGetDrawableInfo(pDrawable->pScreen, pDrawable,
+ (unsigned*)&unused, (unsigned*)&unused,
+ &unused, &unused, &unused, &unused,
+ &unused, &pRects, &unused, &unused,
+ &unused, &pRects)
+ : GL_FALSE;
}
static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
@@ -665,9 +794,9 @@ static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
fakeID = FakeClientID(0);
*(XID *) contextID = fakeID;
- __glXDRIenterServer();
+ __glXDRIenterServer(GL_FALSE);
retval = DRICreateContext(pScreen, visual, fakeID, hw_context);
- __glXDRIleaveServer();
+ __glXDRIleaveServer(GL_FALSE);
return retval;
}
@@ -676,9 +805,9 @@ static GLboolean destroyContext(__DRInativeDisplay *dpy, int screen,
{
GLboolean retval;
- __glXDRIenterServer();
+ __glXDRIenterServer(GL_FALSE);
retval = DRIDestroyContext(screenInfo.screens[screen], context);
- __glXDRIleaveServer();
+ __glXDRIleaveServer(GL_FALSE);
return retval;
}
@@ -693,12 +822,10 @@ createDrawable(__DRInativeDisplay *dpy, int screen,
if (!pDrawable)
return GL_FALSE;
- __glXDRIenterServer();
- retval = DRICreateDrawable(screenInfo.screens[screen],
- drawable,
- pDrawable,
- hHWDrawable);
- __glXDRIleaveServer();
+ __glXDRIenterServer(GL_FALSE);
+ retval = DRICreateDrawable(screenInfo.screens[screen], __pGlxClient,
+ pDrawable, hHWDrawable);
+ __glXDRIleaveServer(GL_FALSE);
return retval;
}
@@ -712,11 +839,10 @@ destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
if (!pDrawable)
return GL_FALSE;
- __glXDRIenterServer();
- retval = DRIDestroyDrawable(screenInfo.screens[screen],
- drawable,
- pDrawable);
- __glXDRIleaveServer();
+ __glXDRIenterServer(GL_FALSE);
+ retval = DRIDestroyDrawable(screenInfo.screens[screen], __pGlxClient,
+ pDrawable);
+ __glXDRIleaveServer(GL_FALSE);
return retval;
}
@@ -753,20 +879,44 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
return GL_FALSE;
}
- __glXDRIenterServer();
+ __glXDRIenterServer(GL_FALSE);
retval = DRIGetDrawableInfo(screenInfo.screens[screen],
pDrawable, index, stamp,
x, y, width, height,
numClipRects, &pClipRects,
backX, backY,
numBackClipRects, &pBackClipRects);
- __glXDRIleaveServer();
+ __glXDRIleaveServer(GL_FALSE);
if (*numClipRects > 0) {
size = sizeof (drm_clip_rect_t) * *numClipRects;
*ppClipRects = xalloc (size);
- if (*ppClipRects != NULL)
- memcpy (*ppClipRects, pClipRects, size);
+
+ /* Clip cliprects to screen dimensions (redirected windows) */
+ if (*ppClipRects != NULL) {
+ ScreenPtr pScreen = screenInfo.screens[screen];
+ int i, j;
+
+ for (i = 0, j = 0; i < *numClipRects; i++) {
+ (*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0);
+ (*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0);
+ (*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width);
+ (*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+ if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 &&
+ (*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) {
+ j++;
+ }
+ }
+
+ if (*numClipRects != j) {
+ *numClipRects = j;
+ *ppClipRects = xrealloc (*ppClipRects,
+ sizeof (drm_clip_rect_t) *
+ *numClipRects);
+ }
+ } else
+ *numClipRects = 0;
}
else {
*ppClipRects = NULL;
@@ -782,7 +932,7 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
*ppBackClipRects = NULL;
}
- return GL_TRUE;
+ return retval;
}
static int
@@ -831,9 +981,12 @@ glxDRIEnterVT (int index, int flags)
LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
+ if (!(*screen->enterVT) (index, flags))
+ return FALSE;
+
glxResumeClients();
- return (*screen->enterVT) (index, flags);
+ return TRUE;
}
static void
@@ -861,9 +1014,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
__DRIframebuffer framebuffer;
int fd = -1;
int status;
- int api_ver = COPY_SUB_BUFFER_INTERNAL_VERSION;
+ int api_ver = 20070121;
drm_magic_t magic;
drmVersionPtr version;
+ int newlyopened;
char *driverName;
drm_handle_t hFB;
int junk;
@@ -875,13 +1029,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
size_t buffer_size;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable")) {
- LogMessage(X_ERROR, "AIGLX: DRI module not loaded\n");
- return NULL;
- }
-
- if (!DRIQueryDirectRenderingCapable(pScreen, &isCapable) || !isCapable) {
- LogMessage(X_ERROR,
+ if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
+ !DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
+ !isCapable) {
+ LogMessage(X_INFO,
"AIGLX: Screen %d is not DRI capable\n", pScreen->myNum);
return NULL;
}
@@ -914,10 +1065,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
goto handle_error;
}
- fd = drmOpen(NULL, BusID);
+ fd = drmOpenOnce(NULL, BusID, &newlyopened);
if (fd < 0) {
- LogMessage(X_ERROR, "AIGLX error: drmOpen failed (%s)\n",
+ LogMessage(X_ERROR, "AIGLX error: drmOpenOnce failed (%s)\n",
strerror(-fd));
goto handle_error;
}
@@ -940,7 +1091,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
drm_version.patch = -1;
}
- if (!DRIAuthConnection(pScreen, magic)) {
+ if (newlyopened && !DRIAuthConnection(pScreen, magic)) {
LogMessage(X_ERROR, "AIGLX error: DRIAuthConnection failed\n");
goto handle_error;
}
@@ -1042,6 +1193,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
goto handle_error;
}
+ DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
+ &screen->texOffsetFinish);
+
__glXScreenInit(&screen->base, pScreen);
buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
@@ -1082,7 +1236,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
xfree(dev_priv);
if (fd >= 0)
- drmClose(fd);
+ drmCloseOnce(fd);
DRICloseConnection(pScreen);