diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.h b/src/mesa/drivers/dri/common/drirenderbuffer.h index cd73b781741..747f92fcdbe 100644 --- a/src/mesa/drivers/dri/common/drirenderbuffer.h +++ b/src/mesa/drivers/dri/common/drirenderbuffer.h @@ -52,8 +52,11 @@ typedef struct { */ GLboolean depthHasSurface; - /* XXX this is for s3v only. A handy flag to know if this is the back - * color buffer. + /** + * A handy flag to know if this is the back color buffer. + * + * \note + * This is currently only used by s3v and tdfx. */ GLboolean backBuffer; } driRenderbuffer; diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c index e9c07bd862e..bd9dade89b5 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_context.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c @@ -657,8 +657,10 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv, GLcontext *newCtx = newFx->glCtx; GET_CURRENT_CONTEXT(curCtx); - if ( newFx->driDrawable != driDrawPriv ) { + if ((newFx->driDrawable != driDrawPriv) + || (newFx->driReadable != driReadPriv)) { newFx->driDrawable = driDrawPriv; + newFx->driReadable = driReadPriv; newFx->dirty = ~0; } else { @@ -676,6 +678,11 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv, newFx->dirty = ~0; } + driUpdateFramebufferSize(newCtx, driDrawPriv); + if (driDrawPriv != driReadPriv) { + driUpdateFramebufferSize(newCtx, driReadPriv); + } + if ( !newFx->Glide.Initialized ) { if ( !tdfxInitContext( driDrawPriv, newFx ) ) return GL_FALSE; @@ -700,7 +707,6 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv, UNLOCK_HARDWARE( newFx ); } - driUpdateFramebufferSize(newCtx, driDrawPriv); _mesa_make_current( newCtx, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.h b/src/mesa/drivers/dri/tdfx/tdfx_context.h index b8349fec73b..89a7a9d6c4e 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_context.h +++ b/src/mesa/drivers/dri/tdfx/tdfx_context.h @@ -895,7 +895,17 @@ struct tdfx_context { /* stuff added for DRI */ __DRIscreenPrivate *driScreen; __DRIcontextPrivate *driContext; - __DRIdrawablePrivate *driDrawable; + + /** + * DRI drawable bound to this context for drawing. + */ + __DRIdrawablePrivate *driDrawable; + + /** + * DRI drawable bound to this context for reading. + */ + __DRIdrawablePrivate *driReadable; + drm_context_t hHWContext; drm_hw_lock_t *driHwLock; int driFd; diff --git a/src/mesa/drivers/dri/tdfx/tdfx_lock.c b/src/mesa/drivers/dri/tdfx/tdfx_lock.c index ae3ba1a8321..a20c91d030a 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_lock.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_lock.c @@ -47,16 +47,20 @@ void tdfxGetLock( tdfxContextPtr fxMesa ) { __DRIcontextPrivate *cPriv = fxMesa->driContext; - __DRIdrawablePrivate *dPriv = cPriv->driDrawablePriv; - __DRIscreenPrivate *sPriv = dPriv->driScreenPriv; + __DRIdrawablePrivate *const drawable = cPriv->driDrawablePriv; + __DRIdrawablePrivate *const readable = cPriv->driReadablePriv; + __DRIscreenPrivate *sPriv = drawable->driScreenPriv; TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) + fxMesa->fxScreen->sarea_priv_offset); - unsigned int stamp = dPriv->lastStamp; + unsigned int stamp = drawable->lastStamp; drmGetLock( fxMesa->driFd, fxMesa->hHWContext, 0 ); - /* This macro will update dPriv's cliprects if needed */ - DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + /* This macro will update drawable's cliprects if needed */ + DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable); + } if ( saPriv->fifoOwner != fxMesa->hHWContext ) { fxMesa->Glide.grDRIImportFifo( saPriv->fifoPtr, saPriv->fifoRead ); @@ -83,10 +87,15 @@ void tdfxGetLock( tdfxContextPtr fxMesa ) } #endif - if ( *dPriv->pStamp != stamp || saPriv->ctxOwner != fxMesa->hHWContext ) { + if ((*drawable->pStamp != stamp) + || (saPriv->ctxOwner != fxMesa->hHWContext)) { + driUpdateFramebufferSize(fxMesa->glCtx, drawable); + if (drawable != readable) { + driUpdateFramebufferSize(fxMesa->glCtx, readable); + } + tdfxUpdateClipping(fxMesa->glCtx); tdfxUploadClipping(fxMesa); - driUpdateFramebufferSize(fxMesa->glCtx, dPriv); } DEBUG_LOCK(); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c index 1a5a2b11090..732270b2bd3 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c @@ -496,9 +496,9 @@ tdfx_readpixels_R5G6B5(GLcontext * ctx, GLint x, GLint y, { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GrLfbInfo_t info; - - const GLint winX = fxMesa->x_offset; - const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + __DRIdrawablePrivate *const readable = fxMesa->driReadable; + const GLint winX = readable->x; + const GLint winY = readable->y + readable->h - 1; const GLint scrX = winX + x; const GLint scrY = winY - y; @@ -554,9 +554,9 @@ tdfx_readpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y, { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GrLfbInfo_t info; - - const GLint winX = fxMesa->x_offset; - const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + __DRIdrawablePrivate *const readable = fxMesa->driReadable; + const GLint winX = readable->x; + const GLint winY = readable->y + readable->h - 1; const GLint scrX = winX + x; const GLint scrY = winY - y; diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c index 5e3d07f65bb..646f5126eb0 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c @@ -73,6 +73,9 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv ) { tdfxScreenPrivate *fxScreen; TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv; + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; if (sPriv->devPrivSize != sizeof(TDFXDRIRec)) { fprintf(stderr,"\nERROR! sizeof(TDFXDRIRec) does not match passed size from device driver\n"); @@ -113,6 +116,10 @@ tdfxCreateScreen( __DRIscreenPrivate *sPriv ) return GL_FALSE; } + if (glx_enable_extension != NULL) { + (*glx_enable_extension)(psc, "GLX_SGI_make_current_read"); + } + return GL_TRUE; } @@ -180,6 +187,7 @@ tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv, driDrawPriv); tdfxSetSpanFunctions(backRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); + backRb->backBuffer = GL_TRUE; } if (mesaVis->depthBits == 16) { @@ -265,7 +273,9 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) return; LOCK_HARDWARE( fxMesa ); fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); +#ifdef DEBUG printf("SwapBuf SetState 1\n"); +#endif fxMesa->Glide.grGlideSetState(fxMesa->Glide.State ); } } @@ -325,7 +335,9 @@ tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) if (ctx->DriverCtx != fxMesa) { fxMesa = TDFX_CONTEXT(ctx); fxMesa->Glide.grSstSelect( fxMesa->Glide.Board ); +#ifdef DEBUG printf("SwapBuf SetState 2\n"); +#endif fxMesa->Glide.grGlideSetState(fxMesa->Glide.State ); } UNLOCK_HARDWARE( fxMesa ); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_span.c b/src/mesa/drivers/dri/tdfx/tdfx_span.c index ee5eb459bee..d9d52d2b6f5 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_span.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_span.c @@ -47,21 +47,19 @@ #define LOCAL_VARS \ - __DRIdrawablePrivate *dPriv = fxMesa->driDrawable; \ - tdfxScreenPrivate *fxPriv = fxMesa->fxScreen; \ - GLboolean isFront = (ctx->DrawBuffer->_ColorDrawBufferMask[0] \ - == BUFFER_BIT_FRONT_LEFT); \ - GLuint pitch = isFront ? (fxMesa->screen_width * BYTESPERPIXEL) \ - : info.strideInBytes; \ - GLuint height = fxMesa->height; \ + driRenderbuffer *drb = (driRenderbuffer *) rb; \ + __DRIdrawablePrivate *const dPriv = drb->dPriv; \ + GLuint pitch = drb->backBuffer ? info.strideInBytes \ + : (drb->pitch * drb->cpp); \ + const GLuint bottom = dPriv->h - 1; \ char *buf = (char *)((char *)info.lfbPtr + \ - dPriv->x * fxPriv->cpp + \ - dPriv->y * pitch); \ + (dPriv->x * drb->cpp) + \ + (dPriv->y * pitch)); \ GLuint p; \ (void) buf; (void) p; -#define Y_FLIP(_y) (height - _y - 1) +#define Y_FLIP(_y) (bottom - _y) #define HW_WRITE_LOCK() \ @@ -71,10 +69,9 @@ UNLOCK_HARDWARE( fxMesa ); \ LOCK_HARDWARE( fxMesa ); \ info.size = sizeof(GrLfbInfo_t); \ - if ( fxMesa->Glide.grLfbLock( GR_LFB_WRITE_ONLY, \ - fxMesa->DrawBuffer, LFB_MODE, \ - GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \ - { + if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer, \ + LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, \ + &info)) { #define HW_WRITE_UNLOCK() \ fxMesa->Glide.grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer );\