diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-08-06 15:50:03 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-08-06 15:50:03 +0000 |
commit | 63e4a046e3f3b91d71d105db23a14ce674b33b2e (patch) | |
tree | ccccb12f9c52927270b8f26555cc04e79a22ff5d /dist | |
parent | 384ebc29841e4f83b776274dc52b1b617859106e (diff) |
backport some code from mesa current (and 7.5) so that the dri2 protocol
is correctly handled. without fixes to mesa and the ddx, the so-called
backwards compat goop that was added just plain does not work and ends
up with rendering bullshit.
Diffstat (limited to 'dist')
-rw-r--r-- | dist/Mesa/include/GL/internal/dri_interface.h | 39 | ||||
-rw-r--r-- | dist/Mesa/src/glx/x11/dri2.c | 70 | ||||
-rw-r--r-- | dist/Mesa/src/glx/x11/dri2.h | 10 | ||||
-rw-r--r-- | dist/Mesa/src/glx/x11/dri2_glx.c | 139 | ||||
-rw-r--r-- | dist/Mesa/src/glx/x11/dri_common.c | 11 | ||||
-rw-r--r-- | dist/Mesa/src/glx/x11/dri_glx.c | 79 | ||||
-rw-r--r-- | dist/Mesa/src/glx/x11/drisw_glx.c | 4 | ||||
-rw-r--r-- | dist/Mesa/src/glx/x11/glxclient.h | 4 | ||||
-rw-r--r-- | dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c | 30 | ||||
-rw-r--r-- | dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c | 179 | ||||
-rw-r--r-- | dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h | 8 | ||||
-rw-r--r-- | dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c | 3 |
12 files changed, 506 insertions, 70 deletions
diff --git a/dist/Mesa/include/GL/internal/dri_interface.h b/dist/Mesa/include/GL/internal/dri_interface.h index 09ae940f6..b4716e4b5 100644 --- a/dist/Mesa/include/GL/internal/dri_interface.h +++ b/dist/Mesa/include/GL/internal/dri_interface.h @@ -78,6 +78,7 @@ typedef struct __DRIswrastExtensionRec __DRIswrastExtension; typedef struct __DRIbufferRec __DRIbuffer; typedef struct __DRIdri2ExtensionRec __DRIdri2Extension; typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension; +typedef struct __DRI2flushExtensionRec __DRI2flushExtension; /*@}*/ @@ -245,6 +246,16 @@ struct __DRItexBufferExtensionRec { __DRIdrawable *pDraw); }; +/** + * Used by drivers that implement DRI2 + */ +#define __DRI2_FLUSH "DRI2_Flush" +#define __DRI2_FLUSH_VERSION 1 +struct __DRI2flushExtensionRec { + __DRIextension base; + void (*flush)(__DRIdrawable *drawable); +}; + /** * XML document describing the configuration options supported by the @@ -626,6 +637,7 @@ struct __DRIswrastExtensionRec { #define __DRI_BUFFER_ACCUM 6 #define __DRI_BUFFER_FAKE_FRONT_LEFT 7 #define __DRI_BUFFER_FAKE_FRONT_RIGHT 8 +#define __DRI_BUFFER_DEPTH_STENCIL 9 /**< Only available with DRI2 1.1 */ struct __DRIbufferRec { unsigned int attachment; @@ -636,7 +648,7 @@ struct __DRIbufferRec { }; #define __DRI_DRI2_LOADER "DRI_DRI2Loader" -#define __DRI_DRI2_LOADER_VERSION 2 +#define __DRI_DRI2_LOADER_VERSION 3 struct __DRIdri2LoaderExtensionRec { __DRIextension base; @@ -657,6 +669,31 @@ struct __DRIdri2LoaderExtensionRec { * into __DRIdri2ExtensionRec::createNewDrawable */ void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate); + + + /** + * Get list of buffers from the server + * + * Gets a list of buffer for the specified set of attachments. Unlike + * \c ::getBuffers, this function takes a list of attachments paired with + * opaque \c unsigned \c int value describing the format of the buffer. + * It is the responsibility of the caller to know what the service that + * allocates the buffers will expect to receive for the format. + * + * \param driDrawable Drawable whose buffers are being queried. + * \param width Output where the width of the buffers is stored. + * \param height Output where the height of the buffers is stored. + * \param attachments List of pairs of attachment ID and opaque format + * requested for the drawable. + * \param count Number of attachment / format pairs stored in + * \c attachments. + * \param loaderPrivate Loader's private data that was previously passed + * into __DRIdri2ExtensionRec::createNewDrawable. + */ + __DRIbuffer *(*getBuffersWithFormat)(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate); }; /** diff --git a/dist/Mesa/src/glx/x11/dri2.c b/dist/Mesa/src/glx/x11/dri2.c index f967432b9..ebb298592 100644 --- a/dist/Mesa/src/glx/x11/dri2.c +++ b/dist/Mesa/src/glx/x11/dri2.c @@ -39,6 +39,16 @@ #include "xf86drm.h" #include "dri2.h" +/* Allow the build to work with an older versions of dri2proto.h and + * dri2tokens.h. + */ +#if DRI2_MINOR < 1 +#undef DRI2_MINOR +#define DRI2_MINOR 1 +#define X_DRI2GetBuffersWithFormat 7 +#endif + + static char dri2ExtensionName[] = DRI2_NAME; static XExtensionInfo *dri2Info; static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) @@ -276,6 +286,66 @@ DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable, return buffers; } + +DRI2Buffer *DRI2GetBuffersWithFormat(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 * 2), req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2GetBuffersWithFormat; + req->drawable = drawable; + req->count = count; + p = (CARD32 *) &req[1]; + for (i = 0; i < (count * 2); i++) + p[i] = attachments[i]; + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + *width = rep.width; + *height = rep.height; + *outCount = rep.count; + + buffers = Xmalloc(rep.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(); + + return buffers; +} + + void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, CARD32 dest, CARD32 src) { diff --git a/dist/Mesa/src/glx/x11/dri2.h b/dist/Mesa/src/glx/x11/dri2.h index 356c6bcb5..b0e61f80d 100644 --- a/dist/Mesa/src/glx/x11/dri2.h +++ b/dist/Mesa/src/glx/x11/dri2.h @@ -63,6 +63,16 @@ DRI2GetBuffers(Display *dpy, XID drawable, unsigned int *attachments, int count, int *outCount); +/** + * \note + * This function is only supported with DRI2 version 1.1 or later. + */ +extern DRI2Buffer * +DRI2GetBuffersWithFormat(Display *dpy, XID drawable, + int *width, int *height, + unsigned int *attachments, int count, + int *outCount); + extern void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, CARD32 dest, CARD32 src); diff --git a/dist/Mesa/src/glx/x11/dri2_glx.c b/dist/Mesa/src/glx/x11/dri2_glx.c index c97f9816d..f4865aecb 100644 --- a/dist/Mesa/src/glx/x11/dri2_glx.c +++ b/dist/Mesa/src/glx/x11/dri2_glx.c @@ -47,6 +47,9 @@ #include "dri2.h" #include "dri_common.h" +#undef DRI2_MINOR +#define DRI2_MINOR 1 + typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate; typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate; typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate; @@ -77,6 +80,8 @@ struct __GLXDRIdrawablePrivateRec { int have_fake_front; }; +static void dri2WaitX(__GLXDRIdrawable *pdraw); + static void dri2DestroyContext(__GLXDRIcontext *context, __GLXscreenConfigs *psc, Display *dpy) { @@ -202,10 +207,21 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, xrect.width = width; xrect.height = height; +#ifdef __DRI2_FLUSH + if (pdraw->psc->f) + (*pdraw->psc->f->flush)(pdraw->driDrawable); +#endif + region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1); + /* should get a fence ID back from here at some point */ DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region, DRI2BufferFrontLeft, DRI2BufferBackLeft); XFixesDestroyRegion(pdraw->psc->dpy, region); + + /* Refresh the fake front (if present) after we just damaged the real + * front. + */ + dri2WaitX(pdraw); } static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) @@ -230,6 +246,11 @@ static void dri2WaitX(__GLXDRIdrawable *pdraw) xrect.width = priv->width; xrect.height = priv->height; +#ifdef __DRI2_FLUSH + if (pdraw->psc->f) + (*pdraw->psc->f->flush)(pdraw->driDrawable); +#endif + region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1); DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); @@ -250,6 +271,11 @@ static void dri2WaitGL(__GLXDRIdrawable *pdraw) xrect.width = priv->width; xrect.height = priv->height; +#ifdef __DRI2_FLUSH + if (pdraw->psc->f) + (*pdraw->psc->f->flush)(pdraw->driDrawable); +#endif + region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1); DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); @@ -273,30 +299,25 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc) psc->__driScreen = NULL; } -static __DRIbuffer * -dri2GetBuffers(__DRIdrawable *driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *loaderPrivate) +/** + * Process list of buffer received from the server + * + * Processes the list of buffers received in a reply from the server to either + * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat. + */ +static void +process_buffers(__GLXDRIdrawablePrivate *pdraw, DRI2Buffer *buffers, + unsigned count) { - __GLXDRIdrawablePrivate *pdraw = loaderPrivate; - DRI2Buffer *buffers; int i; - buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable, - width, height, attachments, count, out_count); - if (buffers == NULL) - return NULL; - - pdraw->width = *width; - pdraw->height = *height; - pdraw->bufferCount = *out_count; + pdraw->bufferCount = count; pdraw->have_fake_front = 0; pdraw->have_back = 0; /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ - for (i = 0; i < *out_count; i++) { + for (i = 0; i < count; i++) { pdraw->buffers[i].attachment = buffers[i].attachment; pdraw->buffers[i].name = buffers[i].name; pdraw->buffers[i].pitch = buffers[i].pitch; @@ -308,6 +329,51 @@ dri2GetBuffers(__DRIdrawable *driDrawable, pdraw->have_back = 1; } +} + +static __DRIbuffer * +dri2GetBuffers(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + __GLXDRIdrawablePrivate *pdraw = loaderPrivate; + DRI2Buffer *buffers; + + buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable, + width, height, attachments, count, out_count); + if (buffers == NULL) + return NULL; + + pdraw->width = *width; + pdraw->height = *height; + process_buffers(pdraw, buffers, *out_count); + + Xfree(buffers); + + return pdraw->buffers; +} + +static __DRIbuffer * +dri2GetBuffersWithFormat(__DRIdrawable *driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + __GLXDRIdrawablePrivate *pdraw = loaderPrivate; + DRI2Buffer *buffers; + + buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy, + pdraw->base.xDrawable, + width, height, attachments, + count, out_count); + if (buffers == NULL) + return NULL; + + pdraw->width = *width; + pdraw->height = *height; + process_buffers(pdraw, buffers, *out_count); + Xfree(buffers); return pdraw->buffers; @@ -316,7 +382,15 @@ dri2GetBuffers(__DRIdrawable *driDrawable, static const __DRIdri2LoaderExtension dri2LoaderExtension = { { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, dri2GetBuffers, - dri2FlushFrontBuffer + dri2FlushFrontBuffer, + dri2GetBuffersWithFormat, +}; + +static const __DRIdri2LoaderExtension dri2LoaderExtension_old = { + { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, + dri2GetBuffers, + dri2FlushFrontBuffer, + NULL, }; static const __DRIextension *loader_extensions[] = { @@ -325,11 +399,19 @@ static const __DRIextension *loader_extensions[] = { NULL }; +static const __DRIextension *loader_extensions_old[] = { + &dri2LoaderExtension_old.base, + &systemTimeExtension.base, + NULL +}; + static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, __GLXdisplayPrivate *priv) { const __DRIconfig **driver_configs; const __DRIextension **extensions; + const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *) + priv->dri2Display; __GLXDRIscreen *psp; char *driverName, *deviceName; drm_magic_t magic; @@ -347,8 +429,10 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, return NULL; psc->driver = driOpenDriver(driverName); - if (psc->driver == NULL) + if (psc->driver == NULL) { + ErrorMessageF("driver pointer missing\n"); goto handle_error; + } extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); if (extensions == NULL) { @@ -374,15 +458,26 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, return NULL; } - if (drmGetMagic(psc->fd, &magic)) + if (drmGetMagic(psc->fd, &magic)) { + ErrorMessageF("failed to get magic\n"); return NULL; + } - if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) + if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) { + ErrorMessageF("failed to authenticate magic %d\n", magic); return NULL; + } + /* If the server does not support the protocol for + * DRI2GetBuffersWithFormat, don't supply that interface to the driver. + */ psc->__driScreen = - psc->dri2->createNewScreen(screen, psc->fd, - loader_extensions, &driver_configs, psc); + psc->dri2->createNewScreen(screen, psc->fd, + ((pdp->driMinor < 1) + ? loader_extensions_old + : loader_extensions), + &driver_configs, psc); + if (psc->__driScreen == NULL) { ErrorMessageF("failed to create dri screen\n"); return NULL; diff --git a/dist/Mesa/src/glx/x11/dri_common.c b/dist/Mesa/src/glx/x11/dri_common.c index 4fda649e5..6de411111 100644 --- a/dist/Mesa/src/glx/x11/dri_common.c +++ b/dist/Mesa/src/glx/x11/dri_common.c @@ -345,7 +345,9 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2) #endif #ifdef __DRI_SWAP_CONTROL - if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { + /* No DRI2 support for swap_control at the moment, since SwapBuffers + * is done by the X server */ + if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) { psc->swapControl = (__DRIswapControlExtension *) extensions[i]; __glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); __glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); @@ -392,6 +394,13 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2) } #endif +#ifdef __DRI2_FLUSH + if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) { + psc->f = (__DRI2flushExtension *) extensions[i]; + /* internal driver extension, no GL extension exposed */ + } +#endif + /* Ignore unknown extensions */ } } diff --git a/dist/Mesa/src/glx/x11/dri_glx.c b/dist/Mesa/src/glx/x11/dri_glx.c index 372d9d9fc..ac2eb0534 100644 --- a/dist/Mesa/src/glx/x11/dri_glx.c +++ b/dist/Mesa/src/glx/x11/dri_glx.c @@ -40,6 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "glxclient.h" #include "glcontextmodes.h" #include "xf86dri.h" +#include "dri2.h" #include "sarea.h" #include <dlfcn.h> #include <sys/types.h> @@ -75,32 +76,45 @@ struct __GLXDRIcontextPrivateRec { */ static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName) { - int directCapable; - Bool b; - int driverMajor, driverMinor, driverPatch; + int directCapable; + Bool b; + int event, error; + int driverMajor, driverMinor, driverPatch; - *driverName = NULL; + *driverName = NULL; - if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) { - ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n"); - return False; - } - if (!directCapable) { - ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n"); - return False; - } + if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */ + if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) { + ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n"); + return False; + } + if (!directCapable) { + ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n"); + return False; + } - b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, - &driverPatch, driverName); - if (!b) { - ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum); - return False; - } + b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, + &driverPatch, driverName); + if (!b) { + ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum); + return False; + } + + InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", + driverMajor, driverMinor, driverPatch, *driverName, scrNum); - InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", - driverMajor, driverMinor, driverPatch, *driverName, scrNum); + return True; + } else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */ + char *dev; + Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev); - return True; + if (ret) + Xfree(dev); + + return ret; + } + + return False; } /* @@ -291,6 +305,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, drm_handle_t hFB; int junk; const __DRIconfig **driver_configs; + __GLcontextModes *visual; /* DRI protocol version. */ dri_version.major = driDpy->driMajor; @@ -403,6 +418,28 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); + /* Visuals with depth != screen depth are subject to automatic compositing + * in the X server, so DRI1 can't render to them properly. Mark them as + * non-conformant to prevent apps from picking them up accidentally. + */ + for (visual = psc->visuals; visual; visual = visual->next) { + XVisualInfo template; + XVisualInfo *visuals; + int num_visuals; + long mask; + + template.visualid = visual->visualID; + mask = VisualIDMask; + visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals); + + if (visuals) { + if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn)) + visual->visualRating = GLX_NON_CONFORMANT_CONFIG; + + XFree(visuals); + } + } + return psp; handle_error: diff --git a/dist/Mesa/src/glx/x11/drisw_glx.c b/dist/Mesa/src/glx/x11/drisw_glx.c index 5e3d763cf..1c229dde9 100644 --- a/dist/Mesa/src/glx/x11/drisw_glx.c +++ b/dist/Mesa/src/glx/x11/drisw_glx.c @@ -401,10 +401,14 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); + free(driver_configs); + psp->destroyScreen = driDestroyScreen; psp->createContext = driCreateContext; psp->createDrawable = driCreateDrawable; psp->swapBuffers = driSwapBuffers; + psp->waitX = NULL; + psp->waitGL = NULL; return psp; diff --git a/dist/Mesa/src/glx/x11/glxclient.h b/dist/Mesa/src/glx/x11/glxclient.h index d03746d11..3c493b448 100644 --- a/dist/Mesa/src/glx/x11/glxclient.h +++ b/dist/Mesa/src/glx/x11/glxclient.h @@ -519,6 +519,10 @@ struct __GLXscreenConfigsRec { const __DRItexBufferExtension *texBuffer; #endif +#ifdef __DRI2_FLUSH + const __DRI2flushExtension *f; +#endif + #endif /** diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c b/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c index 1dc72980e..342edf711 100644 --- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c @@ -332,8 +332,19 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode) { if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { struct intel_context *const intel = intel_context(ctx); + const GLboolean was_front_buffer_rendering = + intel->is_front_buffer_rendering; - intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT); + intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); + + /* If we weren't front-buffer rendering before but we are now, make sure + * that the front-buffer has actually been allocated. + */ + if (!was_front_buffer_rendering && intel->is_front_buffer_rendering) { + intel_update_renderbuffers(intel->driContext, + intel->driContext->driDrawablePriv); + } } intel_draw_buffer(ctx, ctx->DrawBuffer); @@ -343,6 +354,23 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode) static void intelReadBuffer(GLcontext * ctx, GLenum mode) { + if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { + struct intel_context *const intel = intel_context(ctx); + const GLboolean was_front_buffer_reading = + intel->is_front_buffer_reading; + + intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); + + /* If we weren't front-buffer reading before but we are now, make sure + * that the front-buffer has actually been allocated. + */ + if (!was_front_buffer_reading && intel->is_front_buffer_reading) { + intel_update_renderbuffers(intel->driContext, + intel->driContext->driDrawablePriv); + } + } + if (ctx->ReadBuffer == ctx->DrawBuffer) { /* This will update FBO completeness status. * A framebuffer will be incomplete if the GL_READ_BUFFER setting diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c index ecaf6b45b..90544d454 100644 --- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c +++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c @@ -25,12 +25,12 @@ * **************************************************************************/ - #include "main/glheader.h" #include "main/context.h" #include "main/matrix.h" #include "main/simple_list.h" #include "main/extensions.h" +#include "main/arrayobj.h" #include "main/framebuffer.h" #include "main/imports.h" #include "main/points.h" @@ -66,6 +66,7 @@ #include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ + #ifndef INTEL_DEBUG int INTEL_DEBUG = (0); #endif @@ -100,6 +101,9 @@ int INTEL_DEBUG = (0); #define DRIVER_DATE "20090418 2009Q1" #define DRIVER_DATE_GEM "GEM " DRIVER_DATE + +static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush); + static const GLubyte * intelGetString(GLcontext * ctx, GLenum name) { @@ -203,6 +207,24 @@ intelGetString(GLcontext * ctx, GLenum name) } } +static unsigned +intel_bits_per_pixel(const struct intel_renderbuffer *rb) +{ + switch (rb->Base._ActualFormat) { + case GL_RGB5: + case GL_DEPTH_COMPONENT16: + return 16; + case GL_RGB8: + case GL_RGBA8: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH24_STENCIL8_EXT: + case GL_STENCIL_INDEX8_EXT: + return 32; + default: + return 0; + } +} + void intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) { @@ -210,7 +232,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct intel_renderbuffer *rb; struct intel_region *region, *depth_region; struct intel_context *intel = context->driverPrivate; - __DRIbuffer *buffers; + __DRIbuffer *buffers = NULL; __DRIscreen *screen; int i, count; unsigned int attachments[10]; @@ -222,22 +244,65 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) screen = intel->intelScreen->driScrnPriv; - i = 0; - if (intel_fb->color_rb[0]) - attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - if (intel_fb->color_rb[1]) - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH)) - attachments[i++] = __DRI_BUFFER_DEPTH; - if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL)) - attachments[i++] = __DRI_BUFFER_STENCIL; - - buffers = (*screen->dri2.loader->getBuffers)(drawable, - &drawable->w, - &drawable->h, - attachments, i, - &count, - drawable->loaderPrivate); + if (screen->dri2.loader + && (screen->dri2.loader->base.version > 2) + && (screen->dri2.loader->getBuffersWithFormat != NULL)) { + struct intel_renderbuffer *depth_rb; + struct intel_renderbuffer *stencil_rb; + + i = 0; + if ((intel->is_front_buffer_rendering || + intel->is_front_buffer_reading || + !intel_fb->color_rb[1]) + && intel_fb->color_rb[0]) { + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]); + } + + if (intel_fb->color_rb[1]) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + + if ((depth_rb != NULL) && (stencil_rb != NULL)) { + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + attachments[i++] = intel_bits_per_pixel(depth_rb); + } else if (depth_rb != NULL) { + attachments[i++] = __DRI_BUFFER_DEPTH; + attachments[i++] = intel_bits_per_pixel(depth_rb); + } else if (stencil_rb != NULL) { + attachments[i++] = __DRI_BUFFER_STENCIL; + attachments[i++] = intel_bits_per_pixel(stencil_rb); + } + + buffers = + (*screen->dri2.loader->getBuffersWithFormat)(drawable, + &drawable->w, + &drawable->h, + attachments, i / 2, + &count, + drawable->loaderPrivate); + } else if (screen->dri2.loader) { + i = 0; + if (intel_fb->color_rb[0]) + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (intel_fb->color_rb[1]) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH)) + attachments[i++] = __DRI_BUFFER_DEPTH; + if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL)) + attachments[i++] = __DRI_BUFFER_STENCIL; + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, + &drawable->h, + attachments, i, + &count, + drawable->loaderPrivate); + } if (buffers == NULL) return; @@ -280,6 +345,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) region_name = "dri2 depth buffer"; break; + case __DRI_BUFFER_DEPTH_STENCIL: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + region_name = "dri2 depth / stencil buffer"; + break; + case __DRI_BUFFER_STENCIL: rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); region_name = "dri2 stencil buffer"; @@ -326,6 +396,23 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) intel_renderbuffer_set_region(rb, region); intel_region_release(®ion); + + if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + if (rb != NULL) { + struct intel_region *stencil_region = NULL; + + if (rb->region) { + dri_bo_flink(rb->region->buffer, &name); + if (name == buffers[i].name) + continue; + } + + intel_region_reference(&stencil_region, region); + intel_renderbuffer_set_region(rb, stencil_region); + intel_region_release(&stencil_region); + } + } } driUpdateFramebufferSize(&intel->ctx, drawable); @@ -534,8 +621,8 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) { __DRIscreen *const screen = intel->intelScreen->driScrnPriv; - if (screen->dri2.loader - && (screen->dri2.loader->base.version >= 2) + if (screen->dri2.loader && + (screen->dri2.loader->base.version >= 2) && (screen->dri2.loader->flushFrontBuffer != NULL)) { (*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable, intel->driDrawable->loaderPrivate); @@ -578,7 +665,7 @@ intelFinish(GLcontext * ctx) irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); - if (irb->region) + if (irb && irb->region) dri_bo_wait_rendering(irb->region->buffer); } if (fb->_DepthBuffer) { @@ -704,6 +791,13 @@ intelInitContext(struct intel_context *intel, _mesa_init_point(ctx); ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ + if (IS_965(intelScreen->deviceID)) { + if (MAX_WIDTH > 8192) + ctx->Const.MaxRenderbufferSize = 8192; + } else { + if (MAX_WIDTH > 2048) + ctx->Const.MaxRenderbufferSize = 2048; + } /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); @@ -821,13 +915,50 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->prim.vb_bo = NULL; if (release_texture_heaps) { - /* This share group is about to go away, free our private - * texture object data. + /* Nothing is currently done here to free texture heaps; + * but we're not using the texture heap utilities, so I + * rather think we shouldn't. I've taken a look, and can't + * find any private texture data hanging around anywhere, but + * I'm not yet certain there isn't any at all... */ - if (INTEL_DEBUG & DEBUG_TEXTURE) + /* if (INTEL_DEBUG & DEBUG_TEXTURE) fprintf(stderr, "do something to free texture heaps\n"); + */ } + /* XXX In intelMakeCurrent() below, the context's static regions are + * referenced inside the frame buffer; it's listed as a hack, + * with a comment of "XXX FBO temporary fix-ups!", but + * as long as it's there, we should release the regions here. + * The do/while loop around the block is used to allow the + * "continue" statements inside the block to exit the block, + * to avoid many layers of "if" constructs. + */ + do { + __DRIdrawablePrivate * driDrawPriv = intel->driDrawable; + struct intel_framebuffer *intel_fb; + struct intel_renderbuffer *irbDepth, *irbStencil; + if (!driDrawPriv) { + /* We're already detached from the drawable; exit this block. */ + continue; + } + intel_fb = (struct intel_framebuffer *) driDrawPriv->driverPrivate; + if (!intel_fb) { + /* The frame buffer is already gone; exit this block. */ + continue; + } + irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + irbStencil = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + + /* Usually, the stencil buffer is the same as the depth buffer; + * but they're handled separately in MakeCurrent, so we'll + * handle them separately here. + */ + if (irbStencil && irbStencil->region == intel->depth_region) { + intel_renderbuffer_set_region(irbStencil, NULL); + } + } while (0); + intel_region_release(&intel->front_region); intel_region_release(&intel->back_region); intel_region_release(&intel->depth_region); diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h index 8f87d5680..294ee3122 100644 --- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h +++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h @@ -282,6 +282,14 @@ struct intel_context * easily. */ GLboolean is_front_buffer_rendering; + /** + * Track whether front-buffer is the current read target. + * + * This is closely associated with is_front_buffer_rendering, but may + * be set separately. The DRI2 fake front buffer must be referenced + * either way. + */ + GLboolean is_front_buffer_reading; drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c b/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c index d9315043e..3206724d5 100644 --- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c +++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c @@ -688,12 +688,15 @@ intel_set_span_functions(struct intel_context *intel, struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; uint32_t tiling; +#ifndef __OpenBSD__ /* openbsd uses fenced gtt writes for tiles p{read,write} */ /* If in GEM mode, we need to do the tile address swizzling ourselves, * instead of the fence registers handling it. */ + if (intel->ttm) tiling = irb->region->tiling; else +#endif tiling = I915_TILING_NONE; if (rb->_ActualFormat == GL_RGB5) { |