Index: radeon_ioctl.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v
retrieving revision 1.26
diff -u -r1.26 radeon_ioctl.c
--- radeon_ioctl.c	28 Sep 2002 13:59:37 -0000	1.26
+++ radeon_ioctl.c	29 Sep 2002 14:01:28 -0000
@@ -615,72 +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 int radeonWaitForFrameCompletion( radeonContextPtr rmesa )
-{
+static CARD32 radeonGetLastFrame (radeonContextPtr rmesa) {
    unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
-   RADEONSAREAPrivPtr sarea = rmesa->sarea;
+   int ret;
    CARD32 frame;
-   int wait = 0;
-   int fd = rmesa->dri.fd;
 
-   while ( 1 ) {
-      int ret;
+   if (rmesa->dri.screen->drmMinor >= 4) {
+      drmRadeonGetParam gp;
 
-      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" );
+   }
 
-	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++;
+   return frame;
+}
 
-      if (rmesa->do_irqs) {
-	 drmRadeonIrqEmit ie;
-	 drmRadeonIrqWait iw;
+static int radeonWaitForFrameCompletion( radeonContextPtr 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 (radeonGetLastFrame (rmesa) < sarea->last_frame) {
+	 /* have to wait, justifies emission of another IRQ */
+	 wait = RADEON_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 (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();
+	    }
+	 }
+      }
+   }
+
+   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);
+      }
+      rmesa->irqEmitted = GL_TRUE;
+   } else {
+      rmesa->irqEmitted = GL_FALSE;
    }
 
    if ( RADEON_DEBUG & DEBUG_IOCTL )
