Index: r200_ioctl.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c,v
retrieving revision 1.5
diff -u -r1.5 r200_ioctl.c
--- r200_ioctl.c	28 Sep 2002 14:08:28 -0000	1.5
+++ r200_ioctl.c	30 Sep 2002 17:50:05 -0000
@@ -301,59 +301,82 @@
  * SwapBuffers with client-side throttling
  */
 
-#define R200_MAX_OUTSTANDING	2
+#define R200_IRQ_THRESHOLD 2
 
+static void delay( void ) {
+/* Prevent an optimizing compiler from removing a spin loop */
+}
 
-static int r200WaitForFrameCompletion( r200ContextPtr rmesa )
-{
-   RADEONSAREAPrivPtr sarea = rmesa->sarea;
+static CARD32 r200GetLastFrame (r200ContextPtr rmesa) {
+   drmRadeonGetParam gp;
+   int ret;
    CARD32 frame;
-   int wait = 0;
-   int fd = rmesa->dri.fd;
 
-   while ( 1 ) {
-      drmRadeonGetParam gp;
-      int ret;
-      
-      gp.param = RADEON_PARAM_LAST_FRAME;
-      gp.value = (int *)&frame;
-      ret = drmCommandWriteRead( fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
-      if ( ret ) {
-	 fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
-	 exit(1);
-      }
+   gp.param = RADEON_PARAM_LAST_FRAME;
+   gp.value = (int *)&frame;
+   ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
+			      &gp, sizeof(gp) );
+   if ( ret ) {
+      fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
+      exit(1);
+   }
 
-      if ( sarea->last_frame - frame <= R200_MAX_OUTSTANDING ) {
-	 break;
-      }
-      wait++;
+   return frame;
+}
 
-      if (rmesa->do_irqs) {
-	 drmRadeonIrqEmit ie;
-	 drmRadeonIrqWait iw;
+static int r200WaitForFrameCompletion( r200ContextPtr rmesa )
+{
+   RADEONSAREAPrivPtr sarea = rmesa->sarea;
+   int fd = rmesa->dri.fd;
+   int wait = 0;
+   int ret;
 
-	 ie.irq_seq = &iw.irq_seq;
+   if (rmesa->irqEmitted) {
+      if (r200GetLastFrame (rmesa) < sarea->last_frame) {
+	 /* have to wait, justifies emission of another IRQ */
+	 wait = R200_IRQ_THRESHOLD;
 
-	 ret = drmCommandWriteRead( fd, DRM_RADEON_IRQ_EMIT, &ie, sizeof(ie) );
-	 if ( ret ) {
-	    fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret );
-	    exit(1);
-	 }
-	 
 	 UNLOCK_HARDWARE( rmesa ); 
-	 ret = drmCommandWrite( fd, DRM_RADEON_IRQ_WAIT, &iw, sizeof(iw) );
+	 ret = drmCommandWrite( fd, DRM_RADEON_IRQ_WAIT,
+				&rmesa->iw, sizeof(rmesa->iw) );
 	 if ( ret ) {
 	    fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
 	    exit(1);
 	 }
 	 LOCK_HARDWARE( rmesa ); 
-      } else if (rmesa->do_usleeps) {
-	 UNLOCK_HARDWARE( rmesa ); 
-	 do_usleep(1, __FUNCTION__); 
-	 LOCK_HARDWARE( rmesa ); 
+      }
+   } else {
+      /* no IRQ, busy waiting */
+      while (r200GetLastFrame (rmesa) < sarea->last_frame) {
+	 wait++;
+	 if (rmesa->do_usleeps && !rmesa->do_irqs) {
+	    UNLOCK_HARDWARE( rmesa ); 
+	    do_usleep(1, __FUNCTION__); 
+	    LOCK_HARDWARE( rmesa ); 
+	 } else {
+	    int i;
+	    /* Spin in place a bit so we aren't hammering the bus */
+	    for ( i = 0 ; i < 10000 ; i++ ) {
+	       delay();
+	    }
+	 }
       }
    }
 
+   if (wait >= R200_IRQ_THRESHOLD && rmesa->do_irqs) {
+      drmRadeonIrqEmit ie;
+
+      ie.irq_seq = &rmesa->iw.irq_seq;
+      ret = drmCommandWriteRead( fd, DRM_RADEON_IRQ_EMIT, &ie, sizeof(ie) );
+      if ( ret ) {
+	 fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret );
+	 exit(1);
+      }
+      rmesa->irqEmitted = GL_TRUE;
+   } else {
+      rmesa->irqEmitted = GL_FALSE;
+   }
+
    if ( R200_DEBUG & DEBUG_IOCTL )
       fprintf(stderr, "%s( done, wait=%d )\n", __FUNCTION__, wait);
 
@@ -480,8 +503,6 @@
 /* ================================================================
  * Buffer clear
  */
-#define R200_MAX_CLEARS	256
-
 static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
 			 GLint cx, GLint cy, GLint cw, GLint ch )
 {
@@ -561,7 +582,7 @@
 	 exit(1);
       }
 
-      if ( rmesa->sarea->last_clear - clear <= R200_MAX_OUTSTANDING+1 ) {
+      if ( rmesa->sarea->last_clear - clear <= 1 ) {
 	 break;
       }
       
Index: r200_context.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_context.c,v
retrieving revision 1.7
diff -u -r1.7 r200_context.c
--- r200_context.c	29 Sep 2002 21:38:16 -0000	1.7
+++ r200_context.c	30 Sep 2002 17:50:05 -0000
@@ -422,6 +422,8 @@
    rmesa->do_irqs = (rmesa->dri.drmMinor >= 6 && 
 		     !getenv("R200_NO_IRQS") &&
 		     rmesa->r200Screen->irq);
+   rmesa->irqEmitted = GL_FALSE;
+   rmesa->iw.irq_seq = -1;
 
    rmesa->do_usleeps = !getenv("R200_NO_USLEEPS");
    
Index: r200_context.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r200/r200_context.h,v
retrieving revision 1.4
diff -u -r1.4 r200_context.h
--- r200_context.h	26 Sep 2002 07:58:13 -0000	1.4
+++ r200_context.h	30 Sep 2002 17:50:06 -0000
@@ -803,6 +803,8 @@
     */
    GLuint do_usleeps;
    GLuint do_irqs;
+   GLboolean irqEmitted;
+   drmRadeonIrqWait iw;
 
    /* Drawable, cliprect and scissor information
     */
