On Mon, 2003-01-27 at 10:14, Nathaniel Gray wrote: 
> """
> I guess this doesn't happen with DRI disabled? Looks like pure luck to
> me that RADEONWaitForVerticalSync() ever returns when the DRM handles
> vertical blank interrupts. I'll look into fixing that if noone beats me
> to it.
> """
> 
> True, the problem doesn't occur unless DRI is enabled.

This patch works for me with DRI enabled, can you (or anyone seeing the
problem, for that matter) try it?

There could still be an even worse problem if the vertical blank
interrupt stops working for some reason (I've seen that happen after
some weird 3D client crashes). Another possibility would be polling the
CRTC_VBLANK_SAVE bit in the CRTC_STATUS register. Kevin, Hui, anyone
interested, what do you think?


> """
> > 2.  I was using KDM and after exiting X my machine would lock up as it 
> > tried to restart the login screen.  I think that even without KDM I 
> > couldn't restart X after I started it once.  I'm not positive about 
> > this though.
> 
> Can you verify that? Would be interesting to know.
> """
> 
> Nope, I can't verify it.  I guess my system just got into a bad state 
> somehow.  I'm using 4.2.99.4 right now and have successfully restarted 
> X many times.  

So you have verified that it only happens with a display manager. :)

> I haven't tried using KDM again though.

Probably still happens with that? One possibility is one or more
processes keeping the DRM open (Qt comes to mind) long enough to prevent
the next server generation from enabling the DRI. That causing a lockup
would still be a bug, but this might give opportunities for workarounds.


-- 
Earthling Michel D�nzer (MrCooper)/ Debian GNU/Linux (powerpc) developer
XFree86 and DRI project member   /  CS student, Free Software enthusiast
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v
retrieving revision 1.30
diff -p -u -r1.30 xf86drm.c
--- programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c	2002/12/14 02:44:06	1.30
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c	2003/02/02 02:21:15
@@ -1105,6 +1105,7 @@ int drmWaitVBlank(int fd, drmVBlankPtr v
 
     do {
        ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
+       vbl->request.type &= ~DRM_VBLANK_RELATIVE;
     } while (ret && errno == EINTR);
 
     return ret;
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h,v
retrieving revision 1.6
diff -p -u -r1.6 drm_dma.h
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h	2003/01/29 23:00:43	1.6
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h	2003/02/02 02:21:16
@@ -628,6 +628,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
 	switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
 	case _DRM_VBLANK_RELATIVE:
 		vblwait.request.sequence += atomic_read( &dev->vbl_received );
+		vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
 	case _DRM_VBLANK_ABSOLUTE:
 		break;
 	default:
Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
RCS file: /cvs/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v
retrieving revision 1.84
diff -p -u -r1.84 radeon_driver.c
--- programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2003/01/30 05:31:31	1.84
+++ programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2003/02/02 02:21:24
@@ -664,13 +668,26 @@ static int RADEONINPAL(int idx)
 }
 #endif
 
-/* Wait for vertical sync on primary CRTC */
+/* Wait for vertical sync on primary CRTC; try using the DRM ioctl for this
+ * and poll if that fails
+ */
 void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     int            i;
 
+#ifdef XF86DRI
+    if (info->directRenderingEnabled && info->irq) {
+	drmVBlank vbl;
+
+	vbl.request.type = DRM_VBLANK_RELATIVE;
+	vbl.request.sequence = 1;
+
+	if (!drmWaitVBlank(info->drmFD, &vbl)) return;
+    }
+#endif
+
     OUTREG(RADEON_GEN_INT_STATUS, RADEON_VSYNC_INT_AK);
     for (i = 0; i < RADEON_TIMEOUT; i++) {
 	if (INREG(RADEON_GEN_INT_STATUS) & RADEON_VSYNC_INT) break;

Reply via email to