Index: radeon_context.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v
retrieving revision 1.14
diff -u -r1.14 radeon_context.h
--- radeon_context.h	25 Sep 2002 17:20:30 -0000	1.14
+++ radeon_context.h	28 Sep 2002 19:16:15 -0000
@@ -723,6 +723,7 @@
     */
    GLuint do_usleeps;
    GLuint do_irqs;
+   drmRadeonIrqWait iw;
 
    /* Drawable, cliprect and scissor information
     */
Index: radeon_context.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v
retrieving revision 1.18
diff -u -r1.18 radeon_context.c
--- radeon_context.c	25 Sep 2002 17:20:30 -0000	1.18
+++ radeon_context.c	28 Sep 2002 19:16:15 -0000
@@ -408,6 +408,7 @@
       rmesa->vblwait = GL_TRUE;
 
    rmesa->do_irqs = (rmesa->radeonScreen->irq && !getenv("RADEON_NO_IRQS"));
+   rmesa->iw.irq_seq = -1;
 
    rmesa->do_usleeps = !getenv("RADEON_NO_USLEEPS");
    
Index: radeon_ioctl.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v
retrieving revision 1.24
diff -u -r1.24 radeon_ioctl.c
--- radeon_ioctl.c	25 Sep 2002 17:20:30 -0000	1.24
+++ radeon_ioctl.c	28 Sep 2002 19:16:17 -0000
@@ -623,63 +623,68 @@
 
 static int radeonWaitForFrameCompletion( radeonContextPtr rmesa )
 {
-   unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
    RADEONSAREAPrivPtr sarea = rmesa->sarea;
-   CARD32 frame;
-   int wait = 0;
    int fd = rmesa->dri.fd;
+   int wait = 0;
 
-   while ( 1 ) {
+   if (rmesa->do_irqs) {
       int ret;
+      drmRadeonIrqWait *piw = &rmesa->iw;
+      drmRadeonIrqEmit ie;
 
-      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;
+      /* if there was a previous frame, wait for its IRQ */
+      if (piw->irq_seq != -1) {
+         UNLOCK_HARDWARE( rmesa ); 
+         ret = drmCommandWrite( fd, DRM_RADEON_IRQ_WAIT, piw, sizeof(*piw) );
+         if ( ret ) {
+            fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
+            exit(1);
+         }
+         LOCK_HARDWARE( rmesa ); 
+      }
+
+      /* emit an IRQ for this frame, will be waited for after the next frame */
+      ie.irq_seq = &piw->irq_seq;
+      ret = drmCommandWriteRead( fd, DRM_RADEON_IRQ_EMIT, &ie, sizeof(ie) );
+      if ( ret ) {
+         fprintf( stderr, "%s: drmRadeonIrqEmit: %d\n", __FUNCTION__, ret );
+         exit(1);
       }
-      wait++;
+   } else {
+      unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map;
+      CARD32 frame;
 
-      if (rmesa->do_irqs) {
-	 drmRadeonIrqEmit ie;
-	 drmRadeonIrqWait iw;
+      while ( 1 ) {
+         int ret;
 
-	 ie.irq_seq = &iw.irq_seq;
+         if (rmesa->dri.screen->drmMinor >= 4) {
+            drmRadeonGetParam gp;
 
-	 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) );
-	 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 ); 
+            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 ); 
       }
    }
 
@@ -1090,6 +1095,29 @@
 {
    radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
    radeonFlush( ctx );
+   if (rmesa->do_irqs) {
+      int fd = rmesa->dri.fd;
+      int ret;
+
+      drmRadeonIrqEmit ie;
+      drmRadeonIrqWait iw;
+
+      ie.irq_seq = &iw.irq_seq;
+
+      LOCK_HARDWARE( rmesa );
+      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) );
+      if ( ret ) {
+         fprintf( stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__, ret );
+         exit(1);
+      }
+   }
    radeonWaitForIdle( rmesa );
 }
 
