Michel,

How do these changes for r128 COMMIT_RING look? With these I can run
concurrent xine and glx programs in pci and agp mode with XV dma
disabled.

With XV dma enabled, in both pci and agp mode, I can run xine for some
time without any hangs. But startup a glx program and X will hang until I
kill the glx program, and then X and xine will recover. I guess sync is the
next issue, I have a follow-on question on that below.

The patch also includes a change to RING_SPACE_TEST..., based on
the radeon version, adding a register read fallback for determining ring
space.

The current drm r128 does not have any WAIT_UNTIL_*_IDLE macros.
I assume I'm going to need at least a general idle wait to address sync
issues. The only WAIT_UNTIL mask bit defined in r128_drv.h is for page
flip, are there any other bits available for wait functions?

Henry
diff -ur kernel.orig/r128_drv.h kernel/r128_drv.h
--- kernel.orig/r128_drv.h      Fri Jul  5 01:31:11 2002
+++ kernel/r128_drv.h   Wed Jul 17 22:02:59 2002
@@ -414,10 +414,23 @@
                        r128_update_ring_snapshot( ring );              \
                        if ( ring->space >= ring->high_mark )           \
                                goto __ring_space_done;                 \
-                       DRM_UDELAY(1);                          \
+                       DRM_UDELAY(1);                                  \
                }                                                       \
+                DRM_ERROR( "ring space check from memory failed, reading 
+register...\n" );      \
+               /*                                                      \
+                * If ring space check fails from RAM, try reading the  \
+                *  register directly                                   \
+                */                                                     \
+               ring->space = ( R128_READ( R128_PM4_BUFFER_DL_RPTR )    \
+                               - ring->tail ) * sizeof(u32);           \
+                                                                       \
+               if ( ring->space <= 0 )                                 \
+                       ring->space += ring->size;                      \
+               if ( ring->space >= ring->high_mark )                   \
+                       goto __ring_space_done;                         \
+                                                                       \
                DRM_ERROR( "ring space check failed!\n" );              \
-               return DRM_ERR(EBUSY);                          \
+               return DRM_ERR(EBUSY);                                  \
        }                                                               \
  __ring_space_done:                                                    \
        ;                                                               \
@@ -487,11 +500,16 @@
                        dev_priv->ring.start,                           \
                        write * sizeof(u32) );                          \
        }                                                               \
-       r128_flush_write_combine();                                     \
        dev_priv->ring.tail = write;                                    \
-       R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );                   \
 } while (0)
 
+
+#define COMMIT_RING() do {                                             \
+       r128_flush_write_combine();                                     \
+       R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail );     \
+} while (0)
+
+
 #define OUT_RING( x ) do {                                             \
        if ( R128_VERBOSE ) {                                           \
                DRM_INFO( "   OUT_RING( 0x%08x ) at 0x%x\n",            \
diff -ur kernel.orig/r128_state.c kernel/r128_state.c
--- kernel.orig/r128_state.c    Fri Jul  5 01:31:11 2002
+++ kernel/r128_state.c Wed Jul 17 18:02:19 2002
@@ -1256,6 +1256,7 @@
         */
        dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
 
+       COMMIT_RING();
        return 0;
 }
 
@@ -1281,6 +1282,7 @@
                r128_cce_dispatch_flip( dev );
        }
 
+       COMMIT_RING();
        return 0;
 }
 
@@ -1340,6 +1342,7 @@
 
        r128_cce_dispatch_vertex( dev, buf );
 
+       COMMIT_RING();
        return 0;
 }
 
@@ -1411,6 +1414,7 @@
 
        r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count );
 
+       COMMIT_RING();
        return 0;
 }
 
@@ -1420,6 +1424,7 @@
        drm_device_dma_t *dma = dev->dma;
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_blit_t blit;
+       int ret;
 
        LOCK_TEST_WITH_RETURN( dev );
 
@@ -1437,7 +1442,9 @@
        RING_SPACE_TEST_WITH_RETURN( dev_priv );
        VB_AGE_TEST_WITH_RETURN( dev_priv );
 
-       return r128_cce_dispatch_blit( dev, &blit );
+       ret = r128_cce_dispatch_blit( dev, &blit );
+       COMMIT_RING();
+       return ret;
 }
 
 int r128_cce_depth( DRM_IOCTL_ARGS )
@@ -1445,6 +1452,7 @@
        DRM_DEVICE;
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_depth_t depth;
+       int ret;
 
        LOCK_TEST_WITH_RETURN( dev );
 
@@ -1455,16 +1463,19 @@
 
        switch ( depth.func ) {
        case R128_WRITE_SPAN:
-               return r128_cce_dispatch_write_span( dev, &depth );
+               ret = r128_cce_dispatch_write_span( dev, &depth );
        case R128_WRITE_PIXELS:
-               return r128_cce_dispatch_write_pixels( dev, &depth );
+               ret = r128_cce_dispatch_write_pixels( dev, &depth );
        case R128_READ_SPAN:
-               return r128_cce_dispatch_read_span( dev, &depth );
+               ret = r128_cce_dispatch_read_span( dev, &depth );
        case R128_READ_PIXELS:
-               return r128_cce_dispatch_read_pixels( dev, &depth );
+               ret = r128_cce_dispatch_read_pixels( dev, &depth );
+       default:
+               ret = DRM_ERR(EINVAL);
        }
 
-       return DRM_ERR(EINVAL);
+       COMMIT_RING();
+       return ret;
 }
 
 int r128_cce_stipple( DRM_IOCTL_ARGS )
@@ -1487,6 +1498,7 @@
 
        r128_cce_dispatch_stipple( dev, mask );
 
+       COMMIT_RING();
        return 0;
 }
 
@@ -1562,5 +1574,6 @@
         */
        r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end );
 
+       COMMIT_RING();
        return 0;
 }

Reply via email to