From f56b569e9af356c11869ee49a4669bb01b75397e Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Wed, 13 Aug 2008 11:46:25 -0400 Subject: DRI2: Drop sarea, implement swap buffers in the X server. --- src/glx/x11/dri2.c | 113 ++++++++++++++++++++++++++++++------------ src/glx/x11/dri2.h | 23 +++++++-- src/glx/x11/dri2_glx.c | 128 ++++++++++++++++++++++++------------------------ src/glx/x11/dri_glx.c | 6 +++ src/glx/x11/glxclient.h | 5 +- src/glx/x11/glxcmds.c | 3 +- 6 files changed, 174 insertions(+), 104 deletions(-) (limited to 'src/glx') diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c index e7044ab424..dc60af90c1 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/x11/dri2.c @@ -122,7 +122,11 @@ Bool DRI2Connect(Display *dpy, int screen, return False; } - *sareaHandle = rep.sareaHandle; + if (rep.driverNameLength == 0 && rep.busIdLength == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } *driverName = Xmalloc(rep.driverNameLength + 1); if (*driverName == NULL) { @@ -150,7 +154,7 @@ Bool DRI2Connect(Display *dpy, int screen, UnlockDisplay(dpy); SyncHandle(); - return rep.sareaHandle != 0; + return True; } Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic) @@ -179,74 +183,119 @@ Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic) return rep.authenticated; } -Bool DRI2CreateDrawable(Display *dpy, XID drawable, - unsigned int *handle, unsigned int *head) +void DRI2CreateDrawable(Display *dpy, XID drawable) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2CreateDrawableReply rep; xDRI2CreateDrawableReq *req; - XextCheckExtension (dpy, info, dri2ExtensionName, False); + XextSimpleCheckExtension (dpy, info, dri2ExtensionName); LockDisplay(dpy); GetReq(DRI2CreateDrawable, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2CreateDrawable; req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); +} + +DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable, + int *width, int *height, + unsigned int *attachments, int count, + int *outCount) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2GetBuffersReply rep; + xDRI2GetBuffersReq *req; + DRI2Buffer *buffers; + xDRI2Buffer repBuffer; + CARD32 *p; + int i; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReqExtra(DRI2GetBuffers, count * 4, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2GetBuffers; + req->drawable = drawable; + req->count = count; + p = (CARD32 *) &req[1]; + for (i = 0; i < count; i++) + p[i] = attachments[i]; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); - return False; + return NULL; + } + + *width = rep.width; + *height = rep.height; + *outCount = rep.count; + + buffers = Xmalloc(count * sizeof buffers[0]); + if (buffers == NULL) { + _XEatData(dpy, rep.count * sizeof repBuffer); + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + for (i = 0; i < rep.count; i++) { + _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); + buffers[i].attachment = repBuffer.attachment; + buffers[i].name = repBuffer.name; + buffers[i].pitch = repBuffer.pitch; + buffers[i].cpp = repBuffer.cpp; + buffers[i].flags = repBuffer.flags; } + UnlockDisplay(dpy); SyncHandle(); - *handle = rep.handle; - *head = rep.head; - - return True; + return buffers; } -void DRI2DestroyDrawable(Display *dpy, XID drawable) +void DRI2SwapBuffers(Display *dpy, XID drawable, + int x, int y, int width, int height) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2DestroyDrawableReq *req; + xDRI2SwapBuffersReq *req; + xDRI2SwapBuffersReply rep; XextSimpleCheckExtension (dpy, info, dri2ExtensionName); - XSync(dpy, GL_FALSE); - LockDisplay(dpy); - GetReq(DRI2DestroyDrawable, req); + GetReq(DRI2SwapBuffers, req); req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2DestroyDrawable; + req->dri2ReqType = X_DRI2SwapBuffers; req->drawable = drawable; + req->x = x; + req->y = y; + req->width = width; + req->height = height; + + _XReply(dpy, (xReply *)&rep, 0, xFalse); + UnlockDisplay(dpy); SyncHandle(); } -Bool DRI2ReemitDrawableInfo(Display *dpy, XID drawable, unsigned int *head) +void DRI2DestroyDrawable(Display *dpy, XID drawable) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2ReemitDrawableInfoReply rep; - xDRI2ReemitDrawableInfoReq *req; + xDRI2DestroyDrawableReq *req; - XextCheckExtension (dpy, info, dri2ExtensionName, False); + XextSimpleCheckExtension (dpy, info, dri2ExtensionName); + + XSync(dpy, GL_FALSE); LockDisplay(dpy); - GetReq(DRI2ReemitDrawableInfo, req); + GetReq(DRI2DestroyDrawable, req); req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2ReemitDrawableInfo; + req->dri2ReqType = X_DRI2DestroyDrawable; req->drawable = drawable; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } UnlockDisplay(dpy); SyncHandle(); - - *head = rep.head; - - return True; } diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h index 1dfd0448b2..e57c4ce644 100644 --- a/src/glx/x11/dri2.h +++ b/src/glx/x11/dri2.h @@ -33,6 +33,14 @@ #ifndef _DRI2_H_ #define _DRI2_H_ +typedef struct { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; +} DRI2Buffer; + extern Bool DRI2QueryExtension(Display *display, int *eventBase, int *errorBase); extern Bool @@ -42,12 +50,17 @@ DRI2Connect(Display *display, int screen, char **driverName, char **busId, unsigned int *sareaHandle); extern Bool DRI2AuthConnection(Display *display, int screen, drm_magic_t magic); -extern Bool -DRI2CreateDrawable(Display *display, XID drawable, - unsigned int *handle, unsigned int *head); +extern void +DRI2CreateDrawable(Display *display, XID drawable); extern void DRI2DestroyDrawable(Display *display, XID handle); -extern Bool -DRI2ReemitDrawableInfo(Display *dpy, XID handle, unsigned int *head); +extern DRI2Buffer * +DRI2GetBuffers(Display *dpy, XID drawable, + int *width, int *height, + unsigned int *attachments, int count, + int *outCount); +extern void +DRI2SwapBuffers(Display *dpy, XID drawable, + int x, int y, int width, int height); #endif diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index 0be65bce62..c56adfa558 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -49,6 +49,7 @@ typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate; typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate; +typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate; struct __GLXDRIdisplayPrivateRec { __GLXDRIdisplay base; @@ -67,6 +68,13 @@ struct __GLXDRIcontextPrivateRec { __GLXscreenConfigs *psc; }; +struct __GLXDRIdrawablePrivateRec { + __GLXDRIdrawable base; + __DRIbuffer buffers[5]; + int bufferCount; + int width, height; +}; + static void dri2DestroyContext(__GLXDRIcontext *context, __GLXscreenConfigs *psc, Display *dpy) { @@ -104,7 +112,6 @@ static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc, { __GLXDRIcontextPrivate *pcp, *pcp_shared; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; - const __DRIcoreExtension *core = psc->core; __DRIcontext *shared = NULL; if (shareList) { @@ -118,8 +125,8 @@ static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc, pcp->psc = psc; pcp->driContext = - (*core->createNewContext)(psc->__driScreen, - config->driConfig, shared, pcp); + (*psc->dri2->createNewContext)(psc->__driScreen, + config->driConfig, shared, pcp); gc->__driContext = pcp->driContext; if (pcp->driContext == NULL) { @@ -148,45 +155,40 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc, GLXDrawable drawable, const __GLcontextModes *modes) { - __GLXDRIdrawable *pdraw; + __GLXDRIdrawablePrivate *pdraw; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; - unsigned int handle, head; - const __DRIcoreExtension *core = psc->core; pdraw = Xmalloc(sizeof(*pdraw)); if (!pdraw) return NULL; - pdraw->destroyDrawable = dri2DestroyDrawable; - pdraw->xDrawable = xDrawable; - pdraw->drawable = drawable; - pdraw->psc = psc; - - fprintf(stderr, "calling DRI2CreateDrawable, XID 0x%lx, GLX ID 0x%lx\n", - xDrawable, drawable); - - if (!DRI2CreateDrawable(psc->dpy, xDrawable, &handle, &head)) { - Xfree(pdraw); - return NULL; - } + pdraw->base.destroyDrawable = dri2DestroyDrawable; + pdraw->base.xDrawable = xDrawable; + pdraw->base.drawable = drawable; + pdraw->base.psc = psc; - fprintf(stderr, "success, head 0x%x, handle 0x%x\n", head, handle); + DRI2CreateDrawable(psc->dpy, xDrawable); /* Create a new drawable */ - pdraw->driDrawable = - (*core->createNewDrawable)(psc->__driScreen, - config->driConfig, - handle, - head, - pdraw); - - if (!pdraw->driDrawable) { + pdraw->base.driDrawable = + (*psc->dri2->createNewDrawable)(psc->__driScreen, + config->driConfig, pdraw); + + if (!pdraw->base.driDrawable) { DRI2DestroyDrawable(psc->dpy, drawable); Xfree(pdraw); return NULL; } - return pdraw; + return &pdraw->base; +} + +static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) +{ + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + + DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable, + 0, 0, priv->width, priv->height); } static void dri2DestroyScreen(__GLXscreenConfigs *psc) @@ -197,46 +199,39 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc) psc->__driScreen = NULL; } - -static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail, - void *loaderPrivate) +static __DRIbuffer * +dri2GetBuffers(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) { - __GLXDRIdrawable *pdraw = loaderPrivate; - - DRI2ReemitDrawableInfo(pdraw->psc->dpy, pdraw->drawable, tail); -} - -static void dri2PostDamage(__DRIdrawable *draw, - struct drm_clip_rect *rects, - int numRects, void *loaderPrivate) -{ - XRectangle *xrects; - XserverRegion region; - __GLXDRIdrawable *glxDraw = loaderPrivate; - __GLXscreenConfigs *psc = glxDraw->psc; - Display *dpy = psc->dpy; + __GLXDRIdrawablePrivate *pdraw = loaderPrivate; + DRI2Buffer *buffers; int i; - xrects = malloc(sizeof(XRectangle) * numRects); - if (xrects == NULL) - return; - - for (i = 0; i < numRects; i++) { - xrects[i].x = rects[i].x1; - xrects[i].y = rects[i].y1; - xrects[i].width = rects[i].x2 - rects[i].x1; - xrects[i].height = rects[i].y2 - rects[i].y1; + buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable, + width, height, attachments, count, out_count); + pdraw->width = *width; + pdraw->height = *height; + + /* This assumes the DRI2 buffer attachment tokens matches the + * __DRIbuffer tokens. */ + for (i = 0; i < *out_count; i++) { + pdraw->buffers[i].attachment = buffers[i].attachment; + pdraw->buffers[i].name = buffers[i].name; + pdraw->buffers[i].pitch = buffers[i].pitch; + pdraw->buffers[i].cpp = buffers[i].cpp; + pdraw->buffers[i].flags = buffers[i].flags; } - region = XFixesCreateRegion(dpy, xrects, numRects); - free(xrects); - XDamageAdd(dpy, glxDraw->xDrawable, region); - XFixesDestroyRegion(dpy, region); + + Xfree(buffers); + + return pdraw->buffers; } -static const __DRIloaderExtension dri2LoaderExtension = { - { __DRI_LOADER, __DRI_LOADER_VERSION }, - dri2ReemitDrawableInfo, - dri2PostDamage +static const __DRIdri2LoaderExtension dri2LoaderExtension = { + { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, + dri2GetBuffers, }; static const __DRIextension *loader_extensions[] = { @@ -279,10 +274,12 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_CORE) == 0) psc->core = (__DRIcoreExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_DRI2) == 0) + psc->dri2 = (__DRIdri2Extension *) extensions[i]; } - if (psc->core == NULL) { - ErrorMessageF("core dri extension not found\n"); + if (psc->core == NULL || psc->dri2 == NULL) { + ErrorMessageF("core dri or dri2 extension not found\n"); goto handle_error; } @@ -301,7 +298,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, } psc->__driScreen = - psc->core->createNewScreen(screen, psc->fd, sareaHandle, + psc->dri2->createNewScreen(screen, psc->fd, loader_extensions, &driver_configs, psc); if (psc->__driScreen == NULL) { ErrorMessageF("failed to create dri screen\n"); @@ -316,6 +313,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, psp->destroyScreen = dri2DestroyScreen; psp->createContext = dri2CreateContext; psp->createDrawable = dri2CreateDrawable; + psp->swapBuffers = dri2SwapBuffers; Xfree(driverName); Xfree(busID); diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 08c83a2310..39bf6c430b 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -570,6 +570,11 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc, return pdraw; } +static void driSwapBuffers(__GLXDRIdrawable *pdraw) +{ + (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable); +} + static void driDestroyScreen(__GLXscreenConfigs *psc) { /* Free the direct rendering per screen data */ @@ -641,6 +646,7 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen, psp->destroyScreen = driDestroyScreen; psp->createContext = driCreateContext; psp->createDrawable = driCreateDrawable; + psp->swapBuffers = driSwapBuffers; return psp; } diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index e2b4218200..412511247e 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -123,6 +123,8 @@ struct __GLXDRIscreenRec { XID drawable, GLXDrawable glxDrawable, const __GLcontextModes *modes); + + void (*swapBuffers)(__GLXDRIdrawable *pdraw); }; struct __GLXDRIcontextRec { @@ -141,8 +143,8 @@ struct __GLXDRIdrawableRec { XID xDrawable; XID drawable; __GLXscreenConfigs *psc; - __DRIdrawable *driDrawable; GLenum textureTarget; + __DRIdrawable *driDrawable; }; /* @@ -469,6 +471,7 @@ struct __GLXscreenConfigsRec { const __DRIcoreExtension *core; const __DRIlegacyExtension *legacy; const __DRIswrastExtension *swrast; + const __DRIdri2Extension *dri2; __glxHashTable *drawHash; Display *dpy; int scr, fd; diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 0f0cb6233a..9197130dca 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -855,7 +855,8 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); if (pdraw != NULL) { - (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable); + glFlush(); + (*pdraw->psc->driScreen->swapBuffers)(pdraw); return; } #endif -- cgit v1.2.3