From: Brian Paul Date: Thu, 1 Sep 2005 03:54:34 +0000 (+0000) Subject: Finish up some of the gl_renderbuffer work. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=982e8e4d5c95e9e9040b4b70d7322a2a8a9396d9;p=mesa.git Finish up some of the gl_renderbuffer work. Use driRenderbuffer's offset, pitch fields in the span routines. Remove the SetBuffer driver function. Consolidate the code for setting CTX_RB3D_COLOROFFSET and CTX_RB3D_COLORPITCH state in new radeonUpdateDrawBuffer() function. --- diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index c96f38e0abb..c6a9af9a628 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -69,7 +69,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define need_GL_EXT_secondary_color #include "extension_helper.h" -#define DRIVER_DATE "20050528" +#define DRIVER_DATE "20050831" #include "vblank.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 621a4c65574..8c1c70c1228 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -95,7 +95,6 @@ typedef void (*radeon_point_func)( radeonContextPtr, struct radeon_colorbuffer_state { GLuint clear; - GLint drawOffset, drawPitch; int roundEnable; }; @@ -105,10 +104,6 @@ struct radeon_depthbuffer_state { GLfloat scale; }; -struct radeon_pixel_state { - GLint readOffset, readPitch; -}; - struct radeon_scissor_state { drm_clip_rect_t rect; GLboolean enabled; @@ -434,7 +429,6 @@ struct radeon_state { */ struct radeon_colorbuffer_state color; struct radeon_depthbuffer_state depth; - struct radeon_pixel_state pixel; struct radeon_scissor_state scissor; struct radeon_stencilbuffer_state stencil; struct radeon_stipple_state stipple; diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 53c5d5ca537..92f676015a7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -999,21 +999,7 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) rmesa->swap_count++; (void) (*dri_interface->getUST)( & rmesa->swap_ust ); - if ( rmesa->sarea->pfCurrentPage == 1 ) { - rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; - } else { - rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; - } - - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset - + rmesa->radeonScreen->fbLocation; - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; - if (rmesa->sarea->tiling_enabled) { - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE; - } + radeonUpdateDrawBuffer(rmesa->glCtx); } diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index bb121fc587e..2fc5bc7aefe 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" #include "radeon_state.h" #include "radeon_ioctl.h" +#include "drirenderbuffer.h" #if DEBUG_LOCKING char *prevLockFile = NULL; @@ -51,31 +52,41 @@ int prevLockLine = 0; static void radeonUpdatePageFlipping( radeonContextPtr rmesa ) { - int use_back; - - - rmesa->doPageFlip = rmesa->sarea->pfState; - - use_back = (rmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT); - use_back ^= (rmesa->sarea->pfCurrentPage == 1); - - if ( RADEON_DEBUG & DEBUG_VERBOSE ) - fprintf(stderr, "%s allow %d current %d\n", __FUNCTION__, - rmesa->doPageFlip, - rmesa->sarea->pfCurrentPage ); - - if ( use_back ) { - rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; - } else { - rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + if (rmesa->doPageFlip != rmesa->sarea->pfState + || rmesa->sarea->pfState) { + /* If page flipping is on, re we're turning it on/off now we need + * to update the flipped buffer info. + */ + struct gl_framebuffer *fb = rmesa->glCtx->WinSysDrawBuffer; + driRenderbuffer *front_drb + = (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + driRenderbuffer *back_drb + = (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + + if (rmesa->sarea->pfState && rmesa->sarea->pfCurrentPage == 1) { + /* flipped buffers */ + front_drb->flippedOffset = back_drb->offset; + front_drb->flippedPitch = back_drb->pitch; + back_drb->flippedOffset = front_drb->offset; + back_drb->flippedPitch = front_drb->pitch; + } + else { + /* unflipped buffers */ + front_drb->flippedOffset = front_drb->offset; + front_drb->flippedPitch = front_drb->pitch; + if (back_drb) { + /* back buffer is non-existant when single buffered */ + back_drb->flippedOffset = back_drb->offset; + back_drb->flippedPitch = back_drb->pitch; + } + } + + /* update local state */ + rmesa->doPageFlip = rmesa->sarea->pfState; + + /* set hw.ctx.cmd state here */ + radeonUpdateDrawBuffer(rmesa->glCtx); } - - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset - + rmesa->radeonScreen->fbLocation; - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; } @@ -106,6 +117,7 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) */ DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + if ( rmesa->lastStamp != dPriv->lastStamp ) { radeonUpdatePageFlipping( rmesa ); if (rmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index b3a768c2851..e32cfda0599 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -472,16 +472,9 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, const GLboolean swAccum = mesaVis->accumRedBits > 0; const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; -#if 0 - driDrawPriv->driverPrivate = (void *) - _mesa_create_framebuffer( mesaVis, - swDepth, - swStencil, - swAccum, - swAlpha ); -#else struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + /* front color renderbuffer */ { driRenderbuffer *frontRb = driNewRenderbuffer(GL_RGBA, screen->cpp, @@ -490,6 +483,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); } + /* back color renderbuffer */ if (mesaVis->doubleBufferMode) { driRenderbuffer *backRb = driNewRenderbuffer(GL_RGBA, screen->cpp, @@ -498,12 +492,14 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); } + /* depth renderbuffer */ if (mesaVis->depthBits == 16) { driRenderbuffer *depthRb = driNewRenderbuffer(GL_DEPTH_COMPONENT16, screen->cpp, screen->depthOffset, screen->depthPitch); radeonSetSpanFunctions(depthRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + depthRb->depthHasSurface = screen->depthHasSurface; } else if (mesaVis->depthBits == 24) { driRenderbuffer *depthRb @@ -511,8 +507,10 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, screen->depthOffset, screen->depthPitch); radeonSetSpanFunctions(depthRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + depthRb->depthHasSurface = screen->depthHasSurface; } + /* stencil renderbuffer */ if (mesaVis->stencilBits > 0 && !swStencil) { driRenderbuffer *stencilRb = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, screen->cpp, @@ -529,7 +527,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, swAlpha, GL_FALSE /* aux */); driDrawPriv->driverPrivate = (void *) fb; -#endif + return (driDrawPriv->driverPrivate != NULL); } } diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 2d15078d6df..dcb7af31ec9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -45,44 +45,47 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_span.h" #include "radeon_tex.h" +#include "drirenderbuffer.h" + + #define DBG 0 +#define GET_PTR(X,Y) (sPriv->pFB + drb->flippedOffset \ + + ((dPriv->y + (Y)) * drb->flippedPitch + (dPriv->x + (X))) * drb->cpp) + +/* + * Eventually, try to remove all references to ctx/rmesa here. + * The renderbuffer parameter to the span functions should provide all + * the info needed to read/write the pixels. + * We'll be a step closer to supporting Pbuffer and framebuffer objects then. + */ #define LOCAL_VARS \ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - radeonScreenPtr radeonScreen = rmesa->radeonScreen; \ __DRIscreenPrivate *sPriv = rmesa->dri.screen; \ __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \ - GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp; \ + driRenderbuffer *drb = (driRenderbuffer *) rb; \ GLuint height = dPriv->h; \ - char *buf = (char *)(sPriv->pFB + \ - rmesa->state.color.drawOffset + \ - (dPriv->x * radeonScreen->cpp) + \ - (dPriv->y * pitch)); \ - char *read_buf = (char *)(sPriv->pFB + \ - rmesa->state.pixel.readOffset + \ - (dPriv->x * radeonScreen->cpp) + \ - (dPriv->y * pitch)); \ GLuint p; \ - (void) read_buf; (void) buf; (void) p + (void) p; #define LOCAL_DEPTH_VARS \ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - radeonScreenPtr radeonScreen = rmesa->radeonScreen; \ __DRIscreenPrivate *sPriv = rmesa->dri.screen; \ __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; \ + driRenderbuffer *drb = (driRenderbuffer *) rb; \ GLuint height = dPriv->h; \ GLuint xo = dPriv->x; \ GLuint yo = dPriv->y; \ - char *buf = (char *)(sPriv->pFB + radeonScreen->depthOffset); \ - (void) buf + char *buf = (char *)(sPriv->pFB + drb->offset); + #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS #define Y_FLIP( _y ) (height - _y - 1) -#define HW_LOCK() +#define HW_LOCK() -#define HW_UNLOCK() +#define HW_UNLOCK() @@ -97,8 +100,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TAG(x) radeon##x##_RGB565 #define TAG2(x,y) radeon##x##_RGB565##y +#define GET_SRC_PTR(X,Y) GET_PTR(X, Y) +#define GET_DST_PTR(X,Y) GET_PTR(X, Y) #include "spantmp2.h" + /* 32 bit, ARGB8888 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA @@ -106,6 +112,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define TAG(x) radeon##x##_ARGB8888 #define TAG2(x,y) radeon##x##_ARGB8888##y +#define GET_SRC_PTR(X,Y) GET_PTR(X, Y) +#define GET_DST_PTR(X,Y) GET_PTR(X, Y) #include "spantmp2.h" @@ -119,28 +127,29 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * is calculated, and then wired with x and y to produce the final * memory address. * The chip will do address translation on its own if the surface registers - * are set up correctly. It is not quite enough to get it working with hyperz too... + * are set up correctly. It is not quite enough to get it working with hyperz + * too... */ -static GLuint radeon_mba_z32( radeonContextPtr rmesa, - GLint x, GLint y ) +static GLuint +radeon_mba_z32( const driRenderbuffer *drb, GLint x, GLint y ) { - GLuint pitch = rmesa->radeonScreen->frontPitch; - if (rmesa->radeonScreen->depthHasSurface) { - return 4*(x + y*pitch); + GLuint pitch = drb->pitch; + if (drb->depthHasSurface) { + return 4 * (x + y * pitch); } else { GLuint ba, address = 0; /* a[0..1] = 0 */ ba = (y / 16) * (pitch / 16) + (x / 16); - address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ - address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ + address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ + address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ - address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ - address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= (y & 0x8) << 7; /* a[10] = y[3] */ address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ @@ -149,23 +158,25 @@ static GLuint radeon_mba_z32( radeonContextPtr rmesa, } } -static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, GLint x, GLint y ) + +static INLINE GLuint +radeon_mba_z16( const driRenderbuffer *drb, GLint x, GLint y ) { - GLuint pitch = rmesa->radeonScreen->frontPitch; - if (rmesa->radeonScreen->depthHasSurface) { - return 2*(x + y*pitch); + GLuint pitch = drb->pitch; + if (drb->depthHasSurface) { + return 2 * (x + y * pitch); } else { GLuint ba, address = 0; /* a[0] = 0 */ ba = (y / 16) * (pitch / 32) + (x / 32); - address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ - address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ - address |= (x & 0x8) << 4; /* a[7] = x[3] */ - address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ - address |= (y & 0x8) << 7; /* a[10] = y[3] */ - address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ + address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ + address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ + address |= (x & 0x8) << 4; /* a[7] = x[3] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= ((x & 0x10) ^ (y & 0x10)) << 7;/* a[11] = x[4] ^ y[4] */ address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ return address; @@ -176,19 +187,20 @@ static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, GLint x, GLint y /* 16-bit depth buffer functions */ #define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)(buf + radeon_mba_z16( rmesa, _x + xo, _y + yo )) = d; + *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )) = d; #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + radeon_mba_z16( rmesa, _x + xo, _y + yo )); + d = *(GLushort *)(buf + radeon_mba_z16( drb, _x + xo, _y + yo )); #define TAG(x) radeon##x##_16 #include "depthtmp.h" + /* 24 bit depth, 8 bit stencil depthbuffer functions */ #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( rmesa, _x + xo, _y + yo ); \ + GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ GLuint tmp = *(GLuint *)(buf + offset); \ tmp &= 0xff000000; \ tmp |= ((d) & 0x00ffffff); \ @@ -196,7 +208,7 @@ do { \ } while (0) #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x + xo, \ + d = *(GLuint *)(buf + radeon_mba_z32( drb, _x + xo, \ _y + yo )) & 0x00ffffff; #define TAG(x) radeon##x##_24_8 @@ -211,7 +223,7 @@ do { \ */ #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint offset = radeon_mba_z32( rmesa, _x + xo, _y + yo ); \ + GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ GLuint tmp = *(GLuint *)(buf + offset); \ tmp &= 0x00ffffff; \ tmp |= (((d) & 0xff) << 24); \ @@ -220,7 +232,7 @@ do { \ #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint offset = radeon_mba_z32( rmesa, _x + xo, _y + yo ); \ + GLuint offset = radeon_mba_z32( drb, _x + xo, _y + yo ); \ GLuint tmp = *(GLuint *)(buf + offset); \ tmp &= 0xff000000; \ d = tmp >> 24; \ @@ -230,49 +242,6 @@ do { \ #include "stenciltmp.h" -/* - * This function is called to specify which buffer to read and write - * for software rasterization (swrast) fallbacks. This doesn't necessarily - * correspond to glDrawBuffer() or glReadBuffer() calls. - */ -static void radeonSetBuffer( GLcontext *ctx, - GLframebuffer *colorBuffer, - GLuint bufferBit ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - switch ( bufferBit ) { - case BUFFER_BIT_FRONT_LEFT: - if ( rmesa->sarea->pfCurrentPage == 1 ) { - rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset; - rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch; - rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; - } else { - rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch; - rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; - } - break; - case BUFFER_BIT_BACK_LEFT: - if ( rmesa->sarea->pfCurrentPage == 1 ) { - rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch; - rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; - } else { - rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset; - rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch; - rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; - } - break; - default: - assert(0); - break; - } -} /* Move locking out to get reasonable span performance (10x better * than doing this in HW_LOCK above). WaitForIdle() is the main @@ -298,8 +267,6 @@ static void radeonSpanRenderFinish( GLcontext *ctx ) void radeonInitSpanFuncs( GLcontext *ctx ) { struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); - - swdd->SetBuffer = radeonSetBuffer; swdd->SpanRenderStart = radeonSpanRenderStart; swdd->SpanRenderFinish = radeonSpanRenderFinish; } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index ce23aae1797..e0e55461a2c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" #include "radeon_swtcl.h" #include "radeon_vtxfmt.h" +#include "drirenderbuffer.h" /* ============================================================= * Alpha blending @@ -1647,6 +1648,9 @@ void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode ) } +/** + * Called via glDrawBuffer. + */ static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -1658,7 +1662,8 @@ static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */ /* - * _DrawDestMask is easier to cope with than . + * _ColorDrawBufferMask is easier to cope with than . + * Check for software fallback, update cliprects. */ switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { case BUFFER_BIT_FRONT_LEFT: @@ -1675,19 +1680,9 @@ static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) return; } - /* We want to update the s/w rast state too so that r200SetBuffer() - * gets called. + /* We'll set the drawing engine's offset/pitch parameters later + * when we update other state. */ - _swrast_DrawBuffer(ctx, mode); - - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset + - rmesa->radeonScreen->fbLocation) - & RADEON_COLOROFFSET_MASK); - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; - if (rmesa->sarea->tiling_enabled) { - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE; - } } static void radeonReadBuffer( GLcontext *ctx, GLenum mode ) @@ -2122,12 +2117,55 @@ static void update_texturematrix( GLcontext *ctx ) } +/** + * Tell the card where to render (offset, pitch). + * Effected by glDrawBuffer, etc + */ +void +radeonUpdateDrawBuffer(GLcontext *ctx) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + driRenderbuffer *drb; + + if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { + /* draw to front */ + drb = (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + } + else if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) { + /* draw to back */ + drb = (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + } + else { + /* drawing to multiple buffers, or none */ + return; + } + + assert(drb); + assert(drb->flippedPitch); + + RADEON_STATECHANGE( rmesa, ctx ); + + /* Note: we used the (possibly) page-flipped values */ + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] + = ((drb->flippedOffset + rmesa->radeonScreen->fbLocation) + & RADEON_COLOROFFSET_MASK); + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; + if (rmesa->sarea->tiling_enabled) { + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE; + } +} + void radeonValidateState( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint new_state = rmesa->NewGLState; + if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + radeonUpdateDrawBuffer(ctx); + } + if (new_state & _NEW_TEXTURE) { radeonUpdateTextureState( ctx ); new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */ diff --git a/src/mesa/drivers/dri/radeon/radeon_state.h b/src/mesa/drivers/dri/radeon/radeon_state.h index 07739be9491..e9074f51e7d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.h +++ b/src/mesa/drivers/dri/radeon/radeon_state.h @@ -49,6 +49,7 @@ extern void radeonSetCliprects( radeonContextPtr rmesa, GLenum mode ); extern void radeonRecalcScissorRects( radeonContextPtr rmesa ); extern void radeonUpdateViewportOffset( GLcontext *ctx ); extern void radeonUpdateWindow( GLcontext *ctx ); +extern void radeonUpdateDrawBuffer(GLcontext *ctx); extern void radeonValidateState( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 1caffe132bc..be3635a3809 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -148,6 +148,7 @@ void radeonInitState( radeonContextPtr rmesa ) { GLcontext *ctx = rmesa->glCtx; GLuint color_fmt, depth_fmt, i; + GLint drawPitch, drawOffset; switch ( rmesa->radeonScreen->cpp ) { case 2: @@ -189,14 +190,12 @@ void radeonInitState( radeonContextPtr rmesa ) rmesa->Fallback = 0; if ( ctx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { - rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch; + drawOffset = rmesa->radeonScreen->backOffset; + drawPitch = rmesa->radeonScreen->backPitch; } else { - rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; - rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; + drawOffset = rmesa->radeonScreen->frontOffset; + drawPitch = rmesa->radeonScreen->frontPitch; } - rmesa->state.pixel.readOffset = rmesa->state.color.drawOffset; - rmesa->state.pixel.readPitch = rmesa->state.color.drawPitch; rmesa->hw.max_state_size = 0; @@ -378,13 +377,15 @@ void radeonInitState( radeonContextPtr rmesa ) else rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->state.color.roundEnable; - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((rmesa->state.color.drawOffset + + rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = ((drawOffset + rmesa->radeonScreen->fbLocation) & RADEON_COLOROFFSET_MASK); - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & + rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((drawPitch & RADEON_COLORPITCH_MASK) | RADEON_COLOR_ENDIAN_NO_SWAP); + + /* (fixed size) sarea is initialized to zero afaics so can omit version check. Phew! */ if (rmesa->sarea->tiling_enabled) { rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE;