diff options
Diffstat (limited to 'src/glx')
-rw-r--r-- | src/glx/dri2_glx.c | 41 | ||||
-rw-r--r-- | src/glx/dri_common.c | 5 | ||||
-rw-r--r-- | src/glx/drisw_glx.c | 110 | ||||
-rw-r--r-- | src/glx/glx_pbuffer.c | 227 | ||||
-rw-r--r-- | src/glx/glxclient.h | 4 | ||||
-rw-r--r-- | src/glx/glxcmds.c | 3 | ||||
-rw-r--r-- | src/glx/single2.c | 3 |
7 files changed, 252 insertions, 141 deletions
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 1c344489c0..6058c721da 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -47,7 +47,12 @@ #include "xf86drm.h" #include "dri2.h" #include "dri_common.h" -#include "../../mesa/drivers/dri/common/dri_util.h" + +/* From xmlpool/options.h, user exposed so should be stable */ +#define DRI_CONF_VBLANK_NEVER 0 +#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 +#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 +#define DRI_CONF_VBLANK_ALWAYS_SYNC 3 #undef DRI2_MINOR #define DRI2_MINOR 1 @@ -177,6 +182,7 @@ dri2CreateDrawable(__GLXscreenConfigs * psc, __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; __GLXdisplayPrivate *dpyPriv; __GLXDRIdisplayPrivate *pdp; + GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; pdraw = Xmalloc(sizeof(*pdraw)); if (!pdraw) @@ -187,9 +193,24 @@ dri2CreateDrawable(__GLXscreenConfigs * psc, pdraw->base.drawable = drawable; pdraw->base.psc = psc; pdraw->bufferCount = 0; - pdraw->swap_interval = 1; + pdraw->swap_interval = 1; /* default may be overridden below */ pdraw->have_back = 0; + if (psc->config) + psc->config->configQueryi(psc->__driScreen, "vblank_mode", &vblank_mode); + + switch (vblank_mode) { + case DRI_CONF_VBLANK_NEVER: + case DRI_CONF_VBLANK_DEF_INTERVAL_0: + pdraw->swap_interval = 0; + break; + case DRI_CONF_VBLANK_DEF_INTERVAL_1: + case DRI_CONF_VBLANK_ALWAYS_SYNC: + default: + pdraw->swap_interval = 1; + break; + } + DRI2CreateDrawable(psc->dpy, xDrawable); dpyPriv = __glXInitialize(psc->dpy); @@ -477,7 +498,23 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable, static void dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval) { + __GLXscreenConfigs *psc = pdraw->psc; __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; + + if (psc->config) + psc->config->configQueryi(psc->__driScreen, "vblank_mode", &vblank_mode); + + switch (vblank_mode) { + case DRI_CONF_VBLANK_NEVER: + return; + case DRI_CONF_VBLANK_ALWAYS_SYNC: + if (interval <= 0) + return; + break; + default: + break; + } DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval); priv->swap_interval = interval; diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c index d6ce681d70..429fc6d891 100644 --- a/src/glx/dri_common.c +++ b/src/glx/dri_common.c @@ -403,6 +403,11 @@ dri2BindExtensions(__GLXscreenConfigs *psc) /* internal driver extension, no GL extension exposed */ } #endif + +#ifdef __DRI2_CONFIG_QUERY + if ((strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0)) + psc->config = (__DRI2configQueryExtension *) extensions[i]; +#endif } } diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index d8027cc96d..cdb1d9f4dc 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -53,13 +53,8 @@ struct __GLXDRIdrawablePrivateRec XVisualInfo *visinfo; XImage *ximage; - int bpp; }; -/** - * swrast loader functions - */ - static Bool XCreateDrawable(__GLXDRIdrawablePrivate * pdp, Display * dpy, XID drawable, int visualid) @@ -79,20 +74,21 @@ XCreateDrawable(__GLXDRIdrawablePrivate * pdp, XChangeGC(dpy, pdp->swapgc, GCFunction, &gcvalues); XChangeGC(dpy, pdp->swapgc, GCGraphicsExposures, &gcvalues); - /* create XImage */ + /* visual */ visTemp.screen = DefaultScreen(dpy); visTemp.visualid = visualid; visMask = (VisualScreenMask | VisualIDMask); pdp->visinfo = XGetVisualInfo(dpy, visMask, &visTemp, &num_visuals); - pdp->ximage = XCreateImage(dpy, pdp->visinfo->visual, pdp->visinfo->depth, ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 32, /* bitmap_pad */ - 0); /* bytes_per_line */ - - /* get the true number of bits per pixel */ - pdp->bpp = pdp->ximage->bits_per_pixel; + /* create XImage */ + pdp->ximage = XCreateImage(dpy, + pdp->visinfo->visual, + pdp->visinfo->depth, + ZPixmap, 0, /* format, offset */ + NULL, /* data */ + 0, 0, /* width, height */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ return True; } @@ -107,9 +103,14 @@ XDestroyDrawable(__GLXDRIdrawablePrivate * pdp, Display * dpy, XID drawable) XFreeGC(dpy, pdp->swapgc); } +/** + * swrast loader functions + */ + static void swrastGetDrawableInfo(__DRIdrawable * draw, - int *x, int *y, int *w, int *h, void *loaderPrivate) + int *x, int *y, int *w, int *h, + void *loaderPrivate) { __GLXDRIdrawablePrivate *pdp = loaderPrivate; __GLXDRIdrawable *pdraw = &(pdp->base); @@ -118,26 +119,42 @@ swrastGetDrawableInfo(__DRIdrawable * draw, Window root; Status stat; - unsigned int bw, depth; + unsigned uw, uh, bw, depth; drawable = pdraw->xDrawable; stat = XGetGeometry(dpy, drawable, &root, - x, y, (unsigned int *) w, (unsigned int *) h, - &bw, &depth); + x, y, &uw, &uh, &bw, &depth); + *w = uw; + *h = uh; } +/** + * Align renderbuffer pitch. + * + * This should be chosen by the driver and the loader (libGL, xserver/glx) + * should use the driver provided pitch. + * + * It seems that the xorg loader (that is the xserver loading swrast_dri for + * indirect rendering, not client-side libGL) requires that the pitch is + * exactly the image width padded to 32 bits. XXX + * + * The above restriction can probably be overcome by using ScratchPixmap and + * CopyArea in the xserver, similar to ShmPutImage, and setting the width of + * the scratch pixmap to 'pitch / cpp'. + */ static inline int -bytes_per_line(int w, int bpp, unsigned mul) +bytes_per_line(unsigned pitch_bits, unsigned mul) { unsigned mask = mul - 1; - return ((w * bpp + mask) & ~mask) / 8; + return ((pitch_bits + mask) & ~mask) / 8; } static void swrastPutImage(__DRIdrawable * draw, int op, - int x, int y, int w, int h, char *data, void *loaderPrivate) + int x, int y, int w, int h, + char *data, void *loaderPrivate) { __GLXDRIdrawablePrivate *pdp = loaderPrivate; __GLXDRIdrawable *pdraw = &(pdp->base); @@ -163,7 +180,7 @@ swrastPutImage(__DRIdrawable * draw, int op, ximage->data = data; ximage->width = w; ximage->height = h; - ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32); + ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32); XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h); @@ -171,24 +188,25 @@ swrastPutImage(__DRIdrawable * draw, int op, } static void -swrastGetImage(__DRIdrawable * draw, - int x, int y, int w, int h, char *data, void *loaderPrivate) +swrastGetImage(__DRIdrawable * read, + int x, int y, int w, int h, + char *data, void *loaderPrivate) { - __GLXDRIdrawablePrivate *pdp = loaderPrivate; - __GLXDRIdrawable *pdraw = &(pdp->base); - Display *dpy = pdraw->psc->dpy; - Drawable drawable; + __GLXDRIdrawablePrivate *prp = loaderPrivate; + __GLXDRIdrawable *pread = &(prp->base); + Display *dpy = pread->psc->dpy; + Drawable readable; XImage *ximage; - drawable = pdraw->xDrawable; + readable = pread->xDrawable; - ximage = pdp->ximage; + ximage = prp->ximage; ximage->data = data; ximage->width = w; ximage->height = h; - ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32); + ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32); - XGetSubImage(dpy, drawable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0); + XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0); ximage->data = NULL; } @@ -334,10 +352,17 @@ driCreateDrawable(__GLXscreenConfigs * psc, return pdraw; } -static void -driSwapBuffers(__GLXDRIdrawable * pdraw) +static int64_t +driSwapBuffers(__GLXDRIdrawable * pdraw, + int64_t target_msc, int64_t divisor, int64_t remainder) { + (void) target_msc; + (void) divisor; + (void) remainder; + (*pdraw->psc->core->swapBuffers) (pdraw->driDrawable); + + return 0; } static void @@ -350,6 +375,20 @@ driDestroyScreen(__GLXscreenConfigs * psc) dlclose(psc->driver); } +static void * +driOpenSwrast(void) +{ + void *driver = NULL; + + if (driver == NULL) + driver = driOpenDriver("swrast"); + + if (driver == NULL) + driver = driOpenDriver("swrastg"); + + return driver; +} + static __GLXDRIscreen * driCreateScreen(__GLXscreenConfigs * psc, int screen, __GLXdisplayPrivate * priv) @@ -357,14 +396,13 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, __GLXDRIscreen *psp; const __DRIconfig **driver_configs; const __DRIextension **extensions; - const char *driverName = "swrast"; int i; psp = Xcalloc(1, sizeof *psp); if (psp == NULL) return NULL; - psc->driver = driOpenDriver(driverName); + psc->driver = driOpenSwrast(); if (psc->driver == NULL) goto handle_error; diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c index 6c34cda154..b8d0f21bf0 100644 --- a/src/glx/glx_pbuffer.c +++ b/src/glx/glx_pbuffer.c @@ -133,64 +133,6 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, } -/** - * Destroy a pbuffer. - * - * This function is used to implement \c glXDestroyPbuffer and - * \c glXDestroyGLXPbufferSGIX. - * - * \note - * This function dynamically determines whether to use the SGIX_pbuffer - * version of the protocol or the GLX 1.3 version of the protocol. - * - * \todo - * This function needs to be modified to work with direct-rendering drivers. - */ -static void -DestroyPbuffer(Display * dpy, GLXDrawable drawable) -{ - __GLXdisplayPrivate *priv = __glXInitialize(dpy); - CARD8 opcode; - - if ((dpy == NULL) || (drawable == 0)) { - return; - } - - opcode = __glXSetupForCommand(dpy); - if (!opcode) - return; - - LockDisplay(dpy); - - if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { - xGLXDestroyPbufferReq *req; - - GetReq(GLXDestroyPbuffer, req); - req->reqType = opcode; - req->glxCode = X_GLXDestroyPbuffer; - req->pbuffer = (GLXPbuffer) drawable; - } - else { - xGLXVendorPrivateWithReplyReq *vpreq; - CARD32 *data; - - GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq); - data = (CARD32 *) (vpreq + 1); - - data[0] = (CARD32) drawable; - - vpreq->reqType = opcode; - vpreq->glxCode = X_GLXVendorPrivateWithReply; - vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX; - } - - UnlockDisplay(dpy); - SyncHandle(); - - return; -} - - #ifdef GLX_DIRECT_RENDERING static GLenum determineTextureTarget(const int *attribs, int numAttribs) @@ -214,7 +156,6 @@ determineTextureTarget(const int *attribs, int numAttribs) return target; } - static GLenum determineTextureFormat(const int *attribs, int numAttribs) { @@ -227,6 +168,66 @@ determineTextureFormat(const int *attribs, int numAttribs) return 0; } + +static void +CreateDRIDrawable(Display *dpy, const __GLcontextModes *fbconfig, + XID drawable, XID glxdrawable, + const int *attrib_list, size_t num_attribs) +{ + __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw; + __GLXscreenConfigs *psc; + + psc = &priv->screenConfigs[fbconfig->screen]; + if (psc->driScreen == NULL) + return; + + pdraw = psc->driScreen->createDrawable(psc, drawable, + glxdrawable, fbconfig); + if (pdraw == NULL) { + fprintf(stderr, "failed to create drawable\n"); + return; + } + + if (__glxHashInsert(psc->drawHash, glxdrawable, pdraw)) { + (*pdraw->destroyDrawable) (pdraw); + return; /* FIXME: Check what we're supposed to do here... */ + } + + pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs); + pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs); +} + +static void +DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) +{ + int screen; + __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __GLXscreenConfigs *psc = &priv->screenConfigs[screen]; + + if (pdraw != NULL) { + if (destroy_xdrawable) + XFreePixmap(psc->dpy, pdraw->xDrawable); + (*pdraw->destroyDrawable) (pdraw); + __glxHashDelete(psc->drawHash, drawable); + } +} + +#else + +static void +CreateDRIDrawable(Display *dpy, const __GLcontextModes * fbconfig, + XID drawable, XID glxdrawable, + const int *attrib_list, size_t num_attribs) +{ +} + +static void +DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) +{ +} + #endif /** @@ -391,34 +392,7 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, UnlockDisplay(dpy); SyncHandle(); -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - do { - /* FIXME: Maybe delay __DRIdrawable creation until the drawable - * is actually bound to a context... */ - - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); - __GLXDRIdrawable *pdraw; - __GLXscreenConfigs *psc; - - psc = &priv->screenConfigs[fbconfig->screen]; - if (psc->driScreen == NULL) - break; - pdraw = psc->driScreen->createDrawable(psc, drawable, - req->glxwindow, fbconfig); - if (pdraw == NULL) { - fprintf(stderr, "failed to create drawable\n"); - break; - } - - if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) { - (*pdraw->destroyDrawable) (pdraw); - return None; /* FIXME: Check what we're supposed to do here... */ - } - - pdraw->textureTarget = determineTextureTarget(attrib_list, i); - pdraw->textureFormat = determineTextureFormat(attrib_list, i); - } while (0); -#endif + CreateDRIDrawable(dpy, fbconfig, drawable, req->glxwindow, attrib_list, i); return (GLXDrawable) req->glxwindow; } @@ -426,9 +400,6 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, /** * Destroy a non-pbuffer GLX drawable. - * - * \todo - * This function needs to be modified to work with direct-rendering drivers. */ static void DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) @@ -455,19 +426,7 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) UnlockDisplay(dpy); SyncHandle(); -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - { - int screen; - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); - __GLXscreenConfigs *psc = &priv->screenConfigs[screen]; - - if (pdraw != NULL) { - (*pdraw->destroyDrawable) (pdraw); - __glxHashDelete(psc->drawHash, drawable); - } - } -#endif + DestroyDRIDrawable(dpy, drawable, GL_FALSE); return; } @@ -496,6 +455,7 @@ CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, CARD32 *data; CARD8 opcode; unsigned int i; + Pixmap pixmap; i = 0; if (attrib_list) { @@ -555,10 +515,71 @@ CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, UnlockDisplay(dpy); SyncHandle(); + pixmap = XCreatePixmap(dpy, RootWindow(dpy, fbconfig->screen), + width, height, fbconfig->rgbBits); + + CreateDRIDrawable(dpy, fbconfig, pixmap, id, attrib_list, i); + return id; } /** + * Destroy a pbuffer. + * + * This function is used to implement \c glXDestroyPbuffer and + * \c glXDestroyGLXPbufferSGIX. + * + * \note + * This function dynamically determines whether to use the SGIX_pbuffer + * version of the protocol or the GLX 1.3 version of the protocol. + */ +static void +DestroyPbuffer(Display * dpy, GLXDrawable drawable) +{ + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + CARD8 opcode; + + if ((dpy == NULL) || (drawable == 0)) { + return; + } + + opcode = __glXSetupForCommand(dpy); + if (!opcode) + return; + + LockDisplay(dpy); + + if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { + xGLXDestroyPbufferReq *req; + + GetReq(GLXDestroyPbuffer, req); + req->reqType = opcode; + req->glxCode = X_GLXDestroyPbuffer; + req->pbuffer = (GLXPbuffer) drawable; + } + else { + xGLXVendorPrivateWithReplyReq *vpreq; + CARD32 *data; + + GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq); + data = (CARD32 *) (vpreq + 1); + + data[0] = (CARD32) drawable; + + vpreq->reqType = opcode; + vpreq->glxCode = X_GLXVendorPrivateWithReply; + vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX; + } + + UnlockDisplay(dpy); + SyncHandle(); + + DestroyDRIDrawable(dpy, drawable, GL_TRUE); + + return; +} + +/** * Create a new pbuffer. */ PUBLIC GLXPbufferSGIX diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 958e1526c9..57d254ea98 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -557,6 +557,10 @@ struct __GLXscreenConfigsRec const __DRI2flushExtension *f; #endif +#ifdef __DRI2_CONFIG_QUERY + const __DRI2configQueryExtension *config; +#endif + #endif /** diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index e74ae3472e..be9d6f29c0 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -2693,6 +2693,9 @@ __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, if (divisor > 0 && remainder >= divisor) return -1; + if (target_msc == 0 && divisor == 0 && remainder == 0) + remainder = 1; + #ifdef __DRI_SWAP_BUFFER_COUNTER if (psc->counters != NULL) return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc, diff --git a/src/glx/single2.c b/src/glx/single2.c index 9ecf589fff..a1461956b9 100644 --- a/src/glx/single2.c +++ b/src/glx/single2.c @@ -44,6 +44,9 @@ #include <X11/Xlib-xcb.h> #endif /* USE_XCB */ +#if !defined(__GNUC__) +# define __builtin_expect(x, y) x +#endif /* Used for GL_ARB_transpose_matrix */ static void |