Index: radeon_ioctl.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v
retrieving revision 1.27
diff -u -r1.27 radeon_ioctl.c
--- radeon_ioctl.c	29 Sep 2002 20:22:43 -0000	1.27
+++ radeon_ioctl.c	29 Sep 2002 20:36:14 -0000
@@ -615,77 +615,93 @@
  * SwapBuffers with client-side throttling
  */
 
-#define RADEON_MAX_OUTSTANDING	2
+#define RADEON_IRQ_THRESHOLD 2
 
 static void delay( void ) {
 /* Prevent an optimizing compiler from removing a spin loop */
 }
 
+static CARD32 radeonGetLastFrame (radeonContextPtr rmesa) {
+   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
+   int ret;
+   CARD32 frame;
+
+   if (rmesa->dri.screen->drmMinor >= 4) {
+      drmRadeonGetParam gp;
+
+      gp.param = RADEON_PARAM_LAST_FRAME;
+      gp.value = (int *)&frame;
+      ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_GETPARAM,
+				 &gp, sizeof(gp) );
+   } else
+      ret = -EINVAL;
+
+   if ( ret == -EINVAL ) {
+      frame = INREG( RADEON_LAST_FRAME_REG );
+   } else if ( ret ) {
+      fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
+      exit(1);
+   }
+   if ( RADEON_DEBUG & DEBUG_IOCTL ) {
+      fprintf( stderr, "%s( %d )\n", __FUNCTION__, (int)frame );
+      if ( ret ) fprintf( stderr, " ( RADEON_LAST_FRAME register read directly )\n" );
+   }
+
+   return frame;
+}
+
 static int radeonWaitForFrameCompletion( radeonContextPtr rmesa )
 {
    RADEONSAREAPrivPtr sarea = rmesa->sarea;
    int fd = rmesa->dri.fd;
    int wait = 0;
+   int ret;
 
-   if (rmesa->do_irqs) {
-      int ret;
-      drmRadeonIrqWait *iw = &rmesa->iw;
-      drmRadeonIrqEmit ie;
-
-      /* if there was a previous frame, wait for its IRQ */
-      if (iw->irq_seq != -1) {
-         UNLOCK_HARDWARE( rmesa ); 
-         ret = drmCommandWrite( fd, DRM_RADEON_IRQ_WAIT, iw, sizeof(*iw) );
-         if ( ret ) {
-            fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
-            exit(1);
-         }
-         LOCK_HARDWARE( rmesa ); 
+   if (rmesa->irqEmitted) {
+      if (radeonGetLastFrame (rmesa) < sarea->last_frame) {
+	 /* have to wait, justifies emission of another IRQ */
+	 wait = RADEON_IRQ_THRESHOLD;
+
+	 UNLOCK_HARDWARE( rmesa ); 
+	 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 {
+      /* no IRQ, busy waiting */
+      while (radeonGetLastFrame (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();
+	    }
+	 }
       }
+   }
 
-      /* emit an IRQ for this frame, will be waited for after the next frame */
-      ie.irq_seq = &iw->irq_seq;
+   fprintf (stderr, "Waited %d.\r", wait);
+   if (wait >= RADEON_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);
+	 fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret );
+	 exit(1);
       }
+      rmesa->irqEmitted = GL_TRUE;
    } else {
-      unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
-      CARD32 frame;
-
-      while ( 1 ) {
-         int ret;
-
-         if (rmesa->dri.screen->drmMinor >= 4) {
-            drmRadeonGetParam gp;
-
-            gp.param = RADEON_PARAM_LAST_FRAME;
-            gp.value = (int *)&frame;
-            ret = drmCommandWriteRead( fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp) );
-         } else
-            ret = -EINVAL;
-
-         if ( ret == -EINVAL ) {
-            frame = INREG( RADEON_LAST_FRAME_REG );
-         } else if ( ret ) {
-            fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );
-            exit(1);
-         }
-         if ( RADEON_DEBUG & DEBUG_IOCTL ) {
-            fprintf( stderr, "%s( %d )\n", __FUNCTION__, (int)frame );
-            if ( ret ) fprintf( stderr, " ( RADEON_LAST_FRAME register read directly )\n" );
-         }
-
-         if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) {
-            break;
-         }
-         wait++;
-
-         UNLOCK_HARDWARE( rmesa ); 
-         do_usleep(1, __FUNCTION__); 
-         LOCK_HARDWARE( rmesa ); 
-      }
+      rmesa->irqEmitted = GL_FALSE;
    }
 
    if ( RADEON_DEBUG & DEBUG_IOCTL )
Index: radeon_context.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v
retrieving revision 1.19
diff -u -r1.19 radeon_context.c
--- radeon_context.c	29 Sep 2002 20:22:43 -0000	1.19
+++ radeon_context.c	29 Sep 2002 20:36:14 -0000
@@ -408,6 +408,7 @@
       rmesa->vblwait = GL_TRUE;
 
    rmesa->do_irqs = (rmesa->radeonScreen->irq && !getenv("RADEON_NO_IRQS"));
+   rmesa->irqEmitted = GL_FALSE;
    rmesa->iw.irq_seq = -1;
 
    rmesa->do_usleeps = !getenv("RADEON_NO_USLEEPS");
Index: radeon_context.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v
retrieving revision 1.15
diff -u -r1.15 radeon_context.h
--- radeon_context.h	29 Sep 2002 20:22:43 -0000	1.15
+++ radeon_context.h	29 Sep 2002 20:36:14 -0000
@@ -723,6 +723,7 @@
     */
    GLuint do_usleeps;
    GLuint do_irqs;
+   GLboolean irqEmitted;
    drmRadeonIrqWait iw;
 
    /* Drawable, cliprect and scissor information
