summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv/i810/i810swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/i810/i810swap.c')
-rw-r--r--xc/lib/GL/mesa/src/drv/i810/i810swap.c315
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;
}