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;
}