diff options
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/i810/i810swap.c')
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i810/i810swap.c | 315 |
1 files changed, 162 insertions, 153 deletions
diff --git a/xc/lib/GL/mesa/src/drv/i810/i810swap.c b/xc/lib/GL/mesa/src/drv/i810/i810swap.c index 3c78921e3..a0f6d8938 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810swap.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810swap.c @@ -1,66 +1,71 @@ + +#include "types.h" +#include "vbrender.h" +#include "i810log.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "mm.h" +#include "i810lib.h" +#include "i810dd.h" +#include "i810dma.h" +#include "i810state.h" +#include "i810swap.h" +#include "i810dma.h" +#include "i810ioctl.h" + /* * i810BackToFront * - * Blit the visible rectangles from the back buffer to the screen - * Can't really do this from a direct context - don't have the clip - * info, and getting it would be a lot slower than just sending a - * request to the server to do the blit there. - * - * drawable -- front buffer - * buf -- back buffer + * Blit the visible rectangles from the back buffer to the screen. + * Respects the frontbuffer cliprects, and applies the offset + * necessary if the backbuffer is positioned elsewhere in the screen. */ -int i810BackToFront(DrawablePtr drawable, - struct i810_dest_buffer *buf) +static int i810BackToFront( i810ContextPtr imesa ) { - RegionPtr prgnClip; - BoxPtr pbox; - int i,nbox; - int ofs, xorg, yorg, pitch; - - if ( !xf86VTSema ) { - i810Error("BackToFront(): !xf86VTSema\n"); - return BadMatch; /* Is this really an error? */ - } - - if ( drawable->width != buf->Width || - drawable->height != buf->Height || - drawable->type != DRAWABLE_WINDOW ) { - i810Error("BackToFront(): bad drawable\n"); - return BadMatch; - } + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i810ScreenPrivate *i810Screen = imesa->i810Screen; - prgnClip = &((WindowPtr)drawable)->clipList; - pbox = REGION_RECTS(prgnClip); - nbox = REGION_NUM_RECTS(prgnClip); - if( !nbox ) return Success; - xorg = drawable->x; - yorg = drawable->y; - pitch = buf->Pitch; - ofs = buf->MemBlock->ofs; + /* Use the frontbuffer cliprects: + */ + XF86DRIClipRectPtr pbox = dPriv->pClipRects; + int nbox = dPriv->numClipRects; + if( nbox ) { - unsigned int BR13 = ((vga256InfoRec.displayWidth * vgaBytesPerPixel) | + int i; + int pitch = i810Screen->backPitch; + + int dx = dPriv->backX - dPriv->x; + int dy = dPriv->backY - dPriv->y; + int ofs = ( i810Screen->backOffset + + dy * i810Screen->backPitch + + dx * i810Screen->cpp); + + unsigned int BR13 = ((i810Screen->fbStride) | (0xCC << 16)); for (i=0; i < nbox; i++, pbox++) { - int x = pbox->x1 - xorg; - int y = pbox->y1 - yorg; int w = pbox->x2 - pbox->x1; int h = pbox->y2 - pbox->y1; - int start = ofs + x*vgaBytesPerPixel + y*pitch; - int dst = ((pbox->x1 + pbox->y1 * vga256InfoRec.displayWidth) * - vgaBytesPerPixel); + int start = ofs + pbox->x1*i810Screen->cpp + pbox->y1*pitch; + int dst = pbox->x1*i810Screen->cpp + pbox->y1*i810Screen->fbStride; + + if (I810_DEBUG&DEBUG_VERBOSE_2D) + fprintf(stderr, "i810BackToFront %d,%d-%dx%d\n", + pbox->x1,pbox->y1,w,h); { - BEGIN_BATCH( 6 ); + BEGIN_BATCH( imesa, 6 ); OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); OUT_BATCH( BR13 ); /* dest pitch, rop */ - OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel)); + OUT_BATCH( (h << 16) | (w * i810Screen->cpp)); OUT_BATCH( dst ); OUT_BATCH( pitch ); /* src pitch */ @@ -76,33 +81,70 @@ int i810BackToFront(DrawablePtr drawable, /* * ClearBox - * Add hardware commands to draw a filled box for the - * debugging display. + * + * Add hardware commands to draw a filled box for the debugging + * display. These are drawn into the current drawbuffer, so should + * work with both front and backbuffer rendering. (However, it + * is only ever called on swapbuffer - ie backbuffer rendering). */ -static void ClearBox( int x, int y, int w, int h, int r, int g, int b ) +static void ClearBox( i810ContextPtr imesa, + int cx, int cy, int cw, int ch, + int r, int g, int b ) { - int start = (i810DB->MemBlock->ofs + - y * i810DB->Pitch + - x * vgaBytesPerPixel); - - BEGIN_BATCH(6); - - OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); - OUT_BATCH( BR13_SOLID_PATTERN | - (0xF0 << 16) | - i810DB->Pitch ); - OUT_BATCH( (h << 16) | (w * vgaBytesPerPixel)); - OUT_BATCH( start ); - OUT_BATCH( i810PackColor( i810DB->Format, r, g, b, 0 ) ); - OUT_BATCH( 0 ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i810ScreenPrivate *i810Screen = imesa->i810Screen; + + int _nc = imesa->numClipRects; + + while (_nc--) { + int x1 = cx + dPriv->x; + int y1 = cy + dPriv->y; + int x2 = x1 + cw; + int y2 = y1 + ch; + + { + int rx1 = imesa->pClipRects[_nc].x1; + int ry1 = imesa->pClipRects[_nc].y1; + int rx2 = imesa->pClipRects[_nc].x2; + int ry2 = imesa->pClipRects[_nc].y2; + + + if (x2 < rx1) continue; + if (y2 < ry1) continue; + if (x1 > rx2) continue; + if (y1 > ry2) continue; + if (x1 < rx1) x1 = rx1; + if (y1 < ry1) y1 = ry1; + if (x2 > rx2) x2 = rx2; + if (y2 > ry2) y2 = ry2; + } - if (0) - fprintf(stderr, "box %d,%x %dx%d col %x (%d,%d,%d)\n", x,y,w,h, - i810PackColor( i810DB->Format, r, g, b, 0 ), r, g, b); - ADVANCE_BATCH(); + { + int start = (0 + + y1 * i810Screen->backPitch + + x1 * i810Screen->cpp); + BEGIN_BATCH( imesa, 6 ); + OUT_BATCH( BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3 ); + OUT_BATCH( BR13_SOLID_PATTERN | + (0xF0 << 16) | + i810Screen->backPitch ); + OUT_BATCH( ((y2-y1) << 16) | ((x2-x1) * i810Screen->cpp)); + OUT_BATCH( start ); + OUT_BATCH( i810PackColor( i810Screen->fbFormat, r, g, b, 0 ) ); + OUT_BATCH( 0 ); + + if (I810_DEBUG&DEBUG_VERBOSE_2D) + fprintf(stderr, "box %d,%x %d,%d col %x (%d,%d,%d)\n", + (int)x1,(int)y1, (int)x2,(int)y2, + (int)i810PackColor( i810Screen->fbFormat, r, g, b, 0 ), + (int)r, (int)g, (int)b); + + ADVANCE_BATCH(); + } + } } @@ -111,143 +153,110 @@ static void ClearBox( int x, int y, int w, int h, int r, int g, int b ) * Draw some small boxesin the corner of the buffer * based on some performance information */ -void i810PerformanceBoxes( int is_direct ) { - int w, t; +static void i810PerformanceBoxes( i810ContextPtr imesa ) { - if ( !i810glx.boxes ) - return; - - - /* draw a box to show we are active, so if it is't seen - it means that it is completely software based rendering */ - /* draw a purple box if we are direct rendering */ - if ( is_direct ) { /* purple = direct (client dma) rendering */ - ClearBox( 4, 4, 8, 8, 255, 0, 255 ); - } else if ( i810glx.dmaDriver ) { /* white = server dma rendering */ - ClearBox( 4, 4, 8, 8, 255, 255, 255 ); - } else { /* grey = servery PDMA */ - ClearBox( 4, 4, 8, 8, 128, 128, 128 ); - } + + /* draw a box to show we are active, so if it is't seen it means + that it is completely software based. Purple is traditional for + direct rendering */ + ClearBox( imesa, 4, 4, 8, 8, 255, 0, 255 ); /* draw a red box if we had to wait for drawing to complete (software render or texture swap) */ if ( i810glx.c_drawWaits ) { - ClearBox( 16, 4, 8, 8, 255, 0, 0 ); + ClearBox( imesa, 16, 4, 8, 8, 255, 0, 0 ); i810glx.c_drawWaits = 0; } - /* draw a blue box if the register protection signal was hit */ - if ( i810glx.c_signals ) { - ClearBox( 28, 4, 8, 8, 0, 0, 255 ); - i810glx.c_signals = 0; + /* draw a blue box if the 3d context was lost + */ + if ( i810glx.c_ctxlost ) { + ClearBox( imesa, 28, 4, 8, 8, 0, 0, 255 ); + i810glx.c_ctxlost = 0; } + /* draw an orange box if texture state was stomped */ + if ( i810glx.c_texlost ) { + ClearBox( imesa, 40, 4, 8, 8, 255, 128, 0 ); + i810glx.c_texlost = 0; + } + /* draw a yellow box if textures were swapped */ if ( i810glx.c_textureSwaps ) { - ClearBox( 40, 4, 8, 8, 255, 255, 0 ); + ClearBox( imesa, 56, 4, 8, 8, 255, 255, 0 ); i810glx.c_textureSwaps = 0; } - - + /* draw a green box if we had to wait for dma to complete (full utilization) on the previous frame */ if ( !i810glx.hardwareWentIdle ) { - ClearBox( 64, 4, 8, 8, 0, 255, 0 ); + ClearBox( imesa, 72, 4, 8, 8, 0, 255, 0 ); } i810glx.hardwareWentIdle = 0; +#if 0 /* show buffer utilization */ if ( i810glx.c_dmaFlush > 1 ) { /* draw a solid bar if we flushed more than one buffer */ - ClearBox( 4, 16, 252, 4, 255, 32, 32 ); + ClearBox( imesa, 4, 16, 252, 4, 255, 32, 32 ); } else { - /* draw bars to represent the utilization of primary and secondary buffers */ - ClearBox( 4, 16, 252, 4, 32, 32, 32 ); + /* draw bars to represent the utilization of primary and + secondary buffers */ + ClearBox( imesa, 4, 16, 252, 4, 32, 32, 32 ); t = i810glx.dma_buffer->mem.Size; w = 252 * i810glx.dma_buffer->head / t; if ( w < 1 ) { w = 1; } - ClearBox( 4, 16, w, 4, 196, 128, 128 ); + ClearBox( imesa, 4, 16, w, 4, 196, 128, 128 ); } +#endif + i810glx.c_dmaFlush = 0; } -static void i810SendDmaFlush( void ) + +static void i810EmitFlush( i810ContextPtr imesa ) { - BEGIN_BATCH(2); + BEGIN_BATCH( imesa, 2 ); OUT_BATCH( INST_PARSER_CLIENT | INST_OP_FLUSH ); OUT_BATCH( 0 ); ADVANCE_BATCH(); } - -/* - * Copy the back buffer to the front buffer. If there's no back buffer - * this is a no-op. Only called in indirect contexts. - */ -static void i810ServerSwapBuffers( XSMesaBuffer b ) +void i810SwapBuffers( i810ContextPtr imesa ) { - /* make sure mesa gives us everything */ - if (i810Ctx && i810Ctx->gl_ctx) - glFlush(); + int tmp; - if ( !b->db_state ) { - /* not double buffered, so do nothing */ - } else { - ValidateGC(b->frontbuffer, b->cleargc); - if ( b->backimage ) { - - struct i810_dest_buffer *buf = - (struct i810_dest_buffer *)b->backimage->devPriv; + if (I810_DEBUG & DEBUG_VERBOSE_API) + fprintf(stderr, "i810SwapBuffers()\n"); - if ( buf && buf->Drawable ) { + FLUSH_BATCH( imesa ); + LOCK_HARDWARE( imesa ); + + i810GetGeneralDmaBufferLocked( imesa ); + i810EmitFlush( imesa ); - /* flush the last primitive */ - i810FinishPrimitive(); + if ( i810glx.boxes ) + i810PerformanceBoxes( imesa ); - /* Drop a flush op into the dma stream */ - i810SendDmaFlush(); + i810BackToFront( imesa ); + i810EmitFlush( imesa ); + i810FlushGeneralLocked( imesa ); - /* diagnostic drawing tools */ - i810PerformanceBoxes( 0 ); + /* Throttle app if the last swap hasn't dispatched yet + */ + if (0) + fprintf(stderr, "dispatch age: %d last swap: %d\n", + GET_DISPATCH_AGE(imesa), imesa->lastSwap); + + tmp = GET_ENQUEUE_AGE(imesa); - /* hardware accelerated back to front blit */ - i810BackToFront( (DrawablePtr)b->frontbuffer,buf ); + UNLOCK_HARDWARE( imesa ); - /* make sure all dma is going to get executed if - * everything has gone well, this will be the only flush - * each frame - */ - i810DmaFlush(); + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) + i810WaitAge(imesa, imesa->lastSwap); - } else { - /* Use backimage's dimension (not buffer's) */ - (*b->cleargc->ops->PutImage)((DrawablePtr)b->frontbuffer, - b->cleargc, - b->frontbuffer->depth, - 0, 0, - b->backimage->width, - b->backimage->height, - 0, ZPixmap, b->backimage->data); - } - } else { - /* Copy pixmap to window on server */ - (*b->cleargc->ops->CopyArea)((DrawablePtr)b->backpixmap, - b->frontbuffer, - b->cleargc, - 0, 0, b->width, b->height, - 0, 0); - } - } - - /* report performance counters */ - i810Msg(10, "swapBuffers: c_triangles:%i c_lines:%i c_points:%i c_setup:%i c_textures:%i\n", - i810glx.c_triangles, i810glx.c_lines, i810glx.c_points, i810glx.c_setupPointers, - i810glx.c_textureSwaps ); - i810glx.c_triangles = 0; - i810glx.c_lines = 0; - i810glx.c_points = 0; - i810glx.c_setupPointers = 0; - i810Msg(10, "---------------------------------------------------------\n" ); + imesa->secondLastSwap = imesa->lastSwap; + imesa->lastSwap = tmp; } |