diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 0f8f4efbe47..21f4563e43c 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1.2.5 2002/12/19 12:26:15 keithw Exp $ +# $Id: Makefile,v 1.1.2.6 2002/12/25 12:51:21 keithw Exp $ # Mesa 3-D graphics library # Version: 5.0 @@ -7,7 +7,7 @@ MESA = ../../.. -MESABUILDDIR = $(MESA)/src +MESABUILDDIR = ../.. INCLUDES = -I$(MESABUILDDIR) -I$(MESA)/include -I. -I../common \ -I$(MESABUILDDIR)/miniglx -Iserver @@ -65,10 +65,12 @@ OBJECTS = $(C_SOURCES:.c=.o) \ ##### TARGETS ##### -default: radeon_dri.so +default: radeon_dri.so install radeon_dri.so: $(COREMESA) $(OBJECTS) Makefile - rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(COREMESA) -L$(MESA)/src/miniglx -lGL -lc -lm && \ + rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(COREMESA) -L$(MESA)/src/miniglx -lGL -lc -lm + +install: rm -f $(MESA)/lib/fb_dri.so && \ install -C radeon_dri.so $(MESA)/lib/radeon_dri.so diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index 583e3c51dde..9ea34060b7f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -92,6 +92,9 @@ extern int prevLockLine; do { \ char __ret = 0; \ DEBUG_CHECK_LOCK(); \ + fprintf(stderr, "LOCK_HARDWARE (fd %d, lock %p, ctx %d) in %s\n", \ + rmesa->dri.fd, rmesa->dri.hwLock, rmesa->dri.hwContext, \ + __FUNCTION__); \ DRM_CAS( rmesa->dri.hwLock, rmesa->dri.hwContext, \ (DRM_LOCK_HELD | rmesa->dri.hwContext), __ret ); \ if ( __ret ) \ diff --git a/src/mesa/drivers/dri/radeon/server/radeon_dri.c b/src/mesa/drivers/dri/radeon/server/radeon_dri.c index e142b0fdd0f..9f52efc9020 100644 --- a/src/mesa/drivers/dri/radeon/server/radeon_dri.c +++ b/src/mesa/drivers/dri/radeon/server/radeon_dri.c @@ -49,7 +49,6 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) { unsigned char *RADEONMMIO = dpy->MMIOAddress; unsigned long mode; - unsigned int vendor, device; int ret; int s, l; @@ -66,8 +65,6 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) * particular combination of graphics card and AGP chipset. */ mode = drmAgpGetMode(dpy->drmFD); /* Default mode */ - vendor = drmAgpVendorId(dpy->drmFD); - device = drmAgpDeviceId(dpy->drmFD); /* Disable fast write entirely - too many lockups. */ @@ -131,6 +128,7 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) } fprintf(stderr, "[agp] ring handle = 0x%08lx\n", info->ringHandle); +#if 0 if (drmMap(dpy->drmFD, info->ringHandle, info->ringMapSize, (drmAddressPtr)&info->ring) < 0) { fprintf(stderr, "[agp] Could not map ring\n"); @@ -139,8 +137,9 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) fprintf(stderr, "[agp] Ring mapped at 0x%08lx\n", - (unsigned long)info->ring); - + (unsigned long)info->ring); +#endif + if (drmAddMap(dpy->drmFD, info->ringReadOffset, info->ringReadMapSize, DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) { fprintf(stderr, @@ -152,6 +151,7 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) "[agp] ring read ptr handle = 0x%08lx\n", info->ringReadPtrHandle); +#if 0 if (drmMap(dpy->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, (drmAddressPtr)&info->ringReadPtr) < 0) { fprintf(stderr, @@ -161,7 +161,8 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) fprintf(stderr, "[agp] Ring read ptr mapped at 0x%08lx\n", (unsigned long)info->ringReadPtr); - +#endif + if (drmAddMap(dpy->drmFD, info->bufStart, info->bufMapSize, DRM_AGP, 0, &info->bufHandle) < 0) { fprintf(stderr, @@ -171,7 +172,8 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) fprintf(stderr, "[agp] vertex/indirect buffers handle = 0x%08lx\n", info->bufHandle); - + +#if 0 if (drmMap(dpy->drmFD, info->bufHandle, info->bufMapSize, (drmAddressPtr)&info->buf) < 0) { fprintf(stderr, @@ -181,7 +183,8 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) fprintf(stderr, "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", (unsigned long)info->buf); - +#endif + if (drmAddMap(dpy->drmFD, info->agpTexStart, info->agpTexMapSize, DRM_AGP, 0, &info->agpTexHandle) < 0) { fprintf(stderr, @@ -191,7 +194,8 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) fprintf(stderr, "[agp] AGP texture map handle = 0x%08lx\n", info->agpTexHandle); - + +#if 0 if (drmMap(dpy->drmFD, info->agpTexHandle, info->agpTexMapSize, (drmAddressPtr)&info->agpTex) < 0) { fprintf(stderr, @@ -201,7 +205,8 @@ static int RADEONDRIAgpInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) fprintf(stderr, "[agp] AGP Texture map mapped at 0x%08lx\n", (unsigned long)info->agpTex); - +#endif + /* Initialize Radeon's AGP registers */ /* Ring buffer is at AGP offset 0 */ OUTREG(RADEON_AGP_BASE, info->ringHandle); @@ -305,6 +310,7 @@ static int RADEONDRIBufInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info ) "[drm] Added %d %d byte vertex/indirect buffers\n", info->bufNumBufs, RADEON_BUFFER_SIZE); +#if 0 if (!(info->buffers = drmMapBufs(dpy->drmFD))) { fprintf(stderr, "[drm] Failed to map vertex/indirect buffers list\n"); @@ -314,7 +320,8 @@ static int RADEONDRIBufInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info ) fprintf(stderr, "[drm] Mapped %d vertex/indirect buffers\n", info->buffers->count); - +#endif + return 1; } @@ -360,11 +367,6 @@ static void RADEONDRICPInit(struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info) /* info->CPStarted = 1; */ } -void * -DRIGetSAREAPrivate( struct MiniGLXDisplayRec *dpy ) -{ - return (void *)(((char*)dpy->pSAREA)+sizeof(XF86DRISAREARec)); -} /* Will fbdev set a pitch appropriate for 3d? @@ -402,6 +404,11 @@ static int DRIFinishScreenInit( struct MiniGLXDisplayRec *dpy ) return 0; } + fprintf(stderr, "DRM_LOCK( %d %p %d )\n", + dpy->drmFD, + dpy->pSAREA, + dpy->serverContext); + DRM_LOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext, @@ -491,10 +498,9 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info ) return 0; } memset(dpy->pSAREA, 0, dpy->SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p\n", - dpy->hSAREA, dpy->pSAREA); - - + fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", + dpy->hSAREA, dpy->pSAREA, dpy->SAREASize); + /* Need to AddMap the framebuffer and mmio regions here: */ if (drmAddMap( dpy->drmFD, @@ -504,7 +510,7 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info ) 0, &dpy->hFrameBuffer) < 0) { - drmUnmap(dpy->pSAREA, dpy->SAREASize); +/* drmUnmap(dpy->pSAREA, dpy->SAREASize); */ drmClose(dpy->drmFD); fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); return 0; @@ -705,7 +711,8 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info ) /* Initialize the SAREA private data structure */ { RADEONSAREAPrivPtr pSAREAPriv; - pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate( dpy ); + pSAREAPriv = (RADEONSAREAPrivPtr)(((char*)dpy->pSAREA) + + sizeof(XF86DRISAREARec)); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); } @@ -713,11 +720,24 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info ) DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext); fprintf(stderr, "DRM_UNLOCK finished\n"); + + { + int i; + for (i = 0 ; i < 5 ; i++) { + fprintf(stderr, "%s: locking\n", __FUNCTION__); + DRM_LOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext, 0); + fprintf(stderr, "%s: locked\n", __FUNCTION__); + + DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext); + fprintf(stderr, "DRM_UNLOCK finished\n"); + } + } + /* This is the struct passed to radeon_dri.so for its initialization */ - dpy->driverInfo = malloc(sizeof(RADEONDRIRec)); - dpy->driverInfoSize = sizeof(RADEONDRIRec); - pRADEONDRI = (RADEONDRIPtr)dpy->driverInfo; + dpy->driverClientMsg = malloc(sizeof(RADEONDRIRec)); + dpy->driverClientMsgSize = sizeof(RADEONDRIRec); + pRADEONDRI = (RADEONDRIPtr)dpy->driverClientMsg; pRADEONDRI->deviceID = info->Chipset; pRADEONDRI->width = dpy->VarInfo.xres_virtual; pRADEONDRI->height = dpy->VarInfo.yres_virtual; @@ -841,6 +861,12 @@ int __driInitFBDev( struct MiniGLXDisplayRec *dpy ) if (!RADEONScreenInit( dpy, info )) return 0; +#if 0 + fprintf(stderr, "Now closing drmFD\n"); + drmClose(dpy->drmFD); + dpy->drmFD = 0; +#endif + return 1; } @@ -851,6 +877,8 @@ int RADEONCPStop( struct MiniGLXDisplayRec *dpy ) drmRadeonCPStop stop; int ret, i; + fprintf(stderr, "%s\n", __FUNCTION__); + stop.flush = 1; stop.idle = 1; @@ -895,14 +923,34 @@ int RADEONCPStop( struct MiniGLXDisplayRec *dpy ) void __driHaltFBDev( struct MiniGLXDisplayRec *dpy ) { drmRadeonInit drmInfo; - RADEONInfoPtr info = (RADEONInfoPtr) dpy->driverPrivate; + RADEONInfoPtr info = (RADEONInfoPtr) dpy->driverInfo; - if (!info) + + fprintf(stderr, "%s\n", __FUNCTION__); + + if (!info) { + fprintf(stderr, "no driverInfo\n"); return; + } - /* Stop the CP */ - RADEONCPStop(dpy); + fprintf(stderr, "DRM_LOCK( %d %p %d )\n", + dpy->drmFD, + dpy->pSAREA, + dpy->serverContext); + + fprintf(stderr, "%s: locking\n", __FUNCTION__); + DRM_LOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext, 0); + fprintf(stderr, "%s: locked\n", __FUNCTION__); + + + if (RADEONCPStop(dpy)) { + fprintf(stderr, "RADEONCPStop failed: %d\n", errno); + DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext); + return; + } + + fprintf(stderr, "%s: cp stoped\n", __FUNCTION__); if (info->irq) { drmCtlUninstHandler(dpy->drmFD); info->irq = 0; @@ -915,11 +963,14 @@ void __driHaltFBDev( struct MiniGLXDisplayRec *dpy ) } /* De-allocate all kernel resources */ + + fprintf(stderr, "%s: calling DRM_RADEON_CLEANUP_CP\n", __FUNCTION__); memset(&drmInfo, 0, sizeof(drmRadeonInit)); drmInfo.func = DRM_RADEON_CLEANUP_CP; drmCommandWrite(dpy->drmFD, DRM_RADEON_CP_INIT, &drmInfo, sizeof(drmRadeonInit)); + /* De-allocate all AGP resources */ if (info->agpTex) { drmUnmap(info->agpTex, info->agpTexMapSize); @@ -948,9 +999,11 @@ void __driHaltFBDev( struct MiniGLXDisplayRec *dpy ) /* if (dpy->drmSIGIOHandlerInstalled) */ /* drmRemoveSIGIOHandler(dpy->drmFD); */ + DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext); + drmUnmap(dpy->pSAREA, dpy->SAREASize); drmClose(dpy->drmFD); free(info); - dpy->driverPrivate = 0; + dpy->driverInfo = 0; } diff --git a/src/miniglx/Makefile b/src/miniglx/Makefile index 31726b02acf..b63f9a97fa2 100644 --- a/src/miniglx/Makefile +++ b/src/miniglx/Makefile @@ -19,11 +19,13 @@ LIBS = -ldl -default: libGL.so.1.2 +default: libGL.so.1.2 install drmtest libGL.so.1.2: $(OBJS) Makefile gcc -shared -Wl,-soname,libGL.so -Wl,-Bsymbolic $(OBJS) $(LIBS) -o $@ + +install: rm -f $(MESA)/lib/libGL.so* install -D libGL.so.1.2 $(MESA)/lib/libGL.so.1.2 ln -s libGL.so.1.2 $(MESA)/lib/libGL.so.1 @@ -32,6 +34,10 @@ libGL.so.1.2: $(OBJS) Makefile #miniglx.a: $(OBJECTS) Makefile # rm -f $@ && ar rcv $@ $(OBJECTS) && ranlib $@ + +drmtest: xf86drm.o drmtest.o + rm -f drmtest && $(CC) -o drmtest xf86drm.o drmtest.o + glapi.c: ../glapi.c ln -s ../glapi.c . diff --git a/src/miniglx/dri_util.c b/src/miniglx/dri_util.c index b09a4830f54..b6354e877fa 100644 --- a/src/miniglx/dri_util.c +++ b/src/miniglx/dri_util.c @@ -408,13 +408,16 @@ static void *driCreateContext(Display *dpy, XVisualInfo *vis, static void driDestroyScreen(Display *dpy, int scrn, void *screenPrivate) { __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; + + fprintf(stderr, "%s\n", __FUNCTION__); if (psp) { if (psp->DriverAPI.DestroyScreen) (*psp->DriverAPI.DestroyScreen)(psp); if (psp->fd) { - (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); +/* (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); */ + fprintf(stderr, "%s: Closing DRM fd\n", __FUNCTION__); (void)drmClose(psp->fd); } @@ -431,9 +434,8 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, { __DRIscreenPrivate *psp; char *driverName; - drmHandle hFB, hSAREA; + drmHandle hFB; drmMagic magic; - char *BusID; psp = (__DRIscreenPrivate *)malloc(sizeof(__DRIscreenPrivate)); if (!psp) { @@ -443,12 +445,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, psp->display = dpy; psp->myNum = scrn; - hSAREA = dpy->hSAREA; - BusID = dpy->pciBusID; - - printf("hSAREA = 0x%x BusID = %s\n", (int) hSAREA, BusID); - - psp->fd = drmOpen(NULL,BusID); + psp->fd = drmOpen(NULL,dpy->pciBusID); if (psp->fd < 0) { fprintf(stderr, "libGL error: failed to open DRM: %s\n", strerror(-psp->fd)); free(psp); @@ -498,8 +495,8 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, psp->fbOrigin = 0; psp->fbSize = dpy->FrameBufferSize; psp->fbStride = dpy->VarInfo.xres_virtual * dpy->cpp; - psp->devPrivSize = dpy->driverInfoSize; - psp->pDevPriv = dpy->driverInfo; + psp->devPrivSize = dpy->driverClientMsgSize; + psp->pDevPriv = dpy->driverClientMsg; psp->fbWidth = dpy->VarInfo.xres; psp->fbHeight = dpy->VarInfo.yres; psp->fbBPP = dpy->VarInfo.bits_per_pixel; @@ -509,7 +506,7 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, if (psp->DriverAPI.InitDriver) { if (!(*psp->DriverAPI.InitDriver)(psp)) { fprintf(stderr, "libGL error: InitDriver failed\n"); - (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); +/* (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); */ free(psp->pDevPriv); (void)drmClose(psp->fd); free(psp); diff --git a/src/miniglx/drmtest.c b/src/miniglx/drmtest.c new file mode 100644 index 00000000000..75642dbaec5 --- /dev/null +++ b/src/miniglx/drmtest.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include "xf86drm.h" + +char *pciBusID = "PCI:1:0:0"; +#define DRM_PAGE_SIZE 4096 +void *pSAREA; + + +int client() +{ + int fd, ret, err; + drmContext clientContext; + + fprintf(stderr, "Opening client drm\n"); + + fd = drmOpen(NULL,pciBusID); + if (fd < 0) { + fprintf(stderr, "failed to open DRM: %s\n", strerror(-fd)); + return 1; + } + + + fprintf(stderr, "Create server context\n"); + if ((err = drmCreateContext(fd, &clientContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + + fprintf(stderr, "DRM_LOCK( %d %p %d )\n", fd, pSAREA, clientContext); + DRM_LOCK(fd, pSAREA, clientContext, 0); + fprintf(stderr, "locked\n"); + DRM_UNLOCK(fd, pSAREA, clientContext); + fprintf(stderr, "DRM_UNLOCK finished\n"); + + +/* (void)drmUnmap((drmAddress)pSAREA, DRM_PAGE_SIZE); */ + + + fprintf(stderr, "Closing client drm: %d\n", fd); + ret = drmClose(fd); + fprintf(stderr, "done %d\n", ret); + + return ret; +} + +int main() +{ + char *drmModuleName = "radeon"; + int drmFD; + int err; + int SAREASize; + drmHandle hSAREA; + drmContext serverContext; + + /* Note that drmOpen will try to load the kernel module, if needed. */ + drmFD = drmOpen(drmModuleName, NULL ); + if (drmFD < 0) { + /* failed to open DRM */ + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + + if ((err = drmSetBusid(drmFD, pciBusID)) < 0) { + drmClose(drmFD); + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + drmFD, pciBusID, strerror(-err)); + return 0; + } + + + SAREASize = DRM_PAGE_SIZE; + + if (drmAddMap( drmFD, + 0, + SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &hSAREA) < 0) + { + drmClose(drmFD); + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", + SAREASize, hSAREA); + + if (drmMap( drmFD, + hSAREA, + SAREASize, + (drmAddressPtr)(&pSAREA)) < 0) + { + drmClose(drmFD); + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + } + + memset(pSAREA, 0, SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", + hSAREA, pSAREA, SAREASize); + + fprintf(stderr, "Create server context\n"); + if ((err = drmCreateContext(drmFD, &serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + + fprintf(stderr, "DRM_LOCK( %d %p %d )\n", drmFD, pSAREA, serverContext); + DRM_LOCK(drmFD, pSAREA, serverContext, 0); + fprintf(stderr, "locked\n"); + DRM_UNLOCK(drmFD, pSAREA, serverContext); + fprintf(stderr, "DRM_UNLOCK finished\n"); + + + client(); + + + fprintf(stderr, "DRM_LOCK( %d %p %d )\n", drmFD, pSAREA, serverContext); + DRM_LOCK(drmFD, pSAREA, serverContext, 0); + fprintf(stderr, "locked\n"); + DRM_UNLOCK(drmFD, pSAREA, serverContext); + fprintf(stderr, "DRM_UNLOCK finished\n"); + + + drmUnmap(pSAREA, SAREASize); + fprintf(stderr, "[drm] unmapped SAREA 0x%08lx from %p, size %d\n", + hSAREA, pSAREA, SAREASize); + pSAREA = 0; + + fprintf(stderr, "%s: Closing DRM fd\n", __FUNCTION__); + (void)drmClose(drmFD); + + return 0; +} + + + diff --git a/src/miniglx/miniglx.c b/src/miniglx/miniglx.c index 3e1c70f935e..59c2b9fb8d5 100644 --- a/src/miniglx/miniglx.c +++ b/src/miniglx/miniglx.c @@ -22,7 +22,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* $Id: miniglx.c,v 1.1.4.23 2002/12/22 17:11:05 jrfonseca Exp $ */ +/* $Id: miniglx.c,v 1.1.4.24 2002/12/25 12:51:21 keithw Exp $ */ /** @@ -126,6 +126,10 @@ static GLXContext CurrentContext = NULL; +static void SwitchDisplay(int i_signal) +{ +} + /**********************************************************************/ /** \name FBdev functions */ /**********************************************************************/ @@ -185,6 +189,8 @@ OpenFBDev( Display *dpy ) /* some magic to restore the vt when we exit */ { struct vt_mode vt; + struct sigaction sig_tty; + if (ioctl(dpy->ConsoleFD, VT_ACTIVATE, vtnumber) != 0) printf("ioctl VT_ACTIVATE: %s\n", strerror(errno)); if (ioctl(dpy->ConsoleFD, VT_WAITACTIVE, vtnumber) != 0) @@ -195,7 +201,22 @@ OpenFBDev( Display *dpy ) return GL_FALSE; } + + + /* Set-up tty signal handler to catch the signal we request below */ + memset( &sig_tty, 0, sizeof( sig_tty ) ); + sig_tty.sa_handler = SwitchDisplay; + sigemptyset( &sig_tty.sa_mask ); + if( sigaction( SIGUSR1, &sig_tty, &dpy->OrigSigUsr1 ) ) + { + fprintf(stderr, "error: can't set up signal handler (%s)", + strerror(errno) ); + return GL_FALSE; + } + + vt.mode = VT_PROCESS; + vt.waitv = 0; vt.relsig = SIGUSR1; vt.acqsig = SIGUSR1; if (ioctl(dpy->ConsoleFD, VT_SETMODE, &vt) < 0) { @@ -379,7 +400,7 @@ SetupFBDev( Display *dpy, Window win ) dpy->cpp = dpy->VarInfo.bits_per_pixel / 8; - if (0) + if (1) { int x, y; char *scrn = (char *)dpy->FrameBuffer; @@ -418,7 +439,8 @@ SetupFBDev( Display *dpy, Window win ) /** - * \brief Restore framebuffer to state it was in before we started. + * \brief Restore framebuffer to state it was in before we started + * (undoes work done in SetupFBDev). * * \sa Called from XDestroyWindow(). */ @@ -432,6 +454,10 @@ RestoreFBDev( Display *dpy ) return GL_FALSE; } dpy->VarInfo = dpy->OrigVarInfo; + + munmap(dpy->FrameBuffer, dpy->FrameBufferSize); + munmap(dpy->MMIOAddress, dpy->MMIOSize); + return GL_TRUE; } @@ -442,14 +468,10 @@ RestoreFBDev( Display *dpy ) * \sa Called from XCloseDisplay(). */ static void -CleanupFBDev( Display *dpy ) +CloseFBDev( Display *dpy ) { struct vt_mode VT; - munmap(dpy->FrameBuffer, dpy->FrameBufferSize); - munmap(dpy->MMIOAddress, dpy->MMIOSize); - close(dpy->FrameBufferFD); - /* restore text mode */ ioctl(dpy->ConsoleFD, KDSETMODE, KD_TEXT); @@ -465,6 +487,7 @@ CleanupFBDev( Display *dpy ) dpy->OriginalVT = -1; } + close(dpy->FrameBufferFD); close(dpy->ConsoleFD); } @@ -555,6 +578,7 @@ InitializeScreenConfigs(int *numConfigs, __GLXvisualConfig **configs) */ int __read_config_file( Display *dpy ) { +#if 1 dpy->fbdevDevice = "/dev/fb0"; dpy->clientDriverName = "radeon_dri.so"; dpy->drmModuleName = "radeon"; @@ -566,6 +590,17 @@ int __read_config_file( Display *dpy ) sprintf((char *)dpy->pciBusID, "PCI:%d:%d:%d", dpy->pciBus, dpy->pciDevice, dpy->pciFunc); +#else + dpy->fbdevDevice = "/dev/fb0"; + dpy->clientDriverName = "fb_dri.so"; + dpy->drmModuleName = 0; + dpy->pciBus = 0; + dpy->pciDevice = 0; + dpy->pciFunc = 0; + dpy->chipset = 0; + dpy->pciBusID = 0; +#endif + return 1; } @@ -615,7 +650,7 @@ XOpenDisplay( const char *display_name ) if (!dpy->dlHandle) { fprintf(stderr, "Unable to open %s: %s\n", dpy->clientDriverName, dlerror()); - CleanupFBDev(dpy); + CloseFBDev(dpy); FREE(dpy); return NULL; } @@ -630,6 +665,16 @@ XOpenDisplay( const char *display_name ) return NULL; } + dpy->driverHaltFBDev = (HaltFBDevFunc) dlsym(dpy->dlHandle, + "__driHaltFBDev"); + if (!dpy->driverHaltFBDev) { + fprintf(stderr, "Couldn't find __driHaltFBDev in %s\n", + dpy->clientDriverName); + dlclose(dpy->dlHandle); + FREE(dpy); + return NULL; + } + dpy->createScreen = (CreateScreenFunc) dlsym(dpy->dlHandle, "__driCreateScreen"); if (!dpy->createScreen) { @@ -661,9 +706,11 @@ XOpenDisplay( const char *display_name ) void XCloseDisplay( Display *display ) { - (*display->driScreen.destroyScreen)(display, 0, display->driScreen.private); + if (display->NumWindows) { + XDestroyWindow( display, display->TheWindow ); + } dlclose(display->dlHandle); - CleanupFBDev(display); + CloseFBDev(display); FREE(display); } @@ -791,6 +838,7 @@ XCreateWindow( Display *display, Window parent, int x, int y, * * Need to shut down drm and free dri data in XDestroyWindow, too. */ +#if 1 display->driScreen.private = (*display->createScreen)(display, 0, &(display->driScreen), display->numConfigs, @@ -813,10 +861,18 @@ XCreateWindow( Display *display, Window parent, int x, int y, return NULL; } +#endif + display->NumWindows++; display->TheWindow = win; - return win; + if (0) { + fprintf(stderr, "Now, destroy it!\n"); + XDestroyWindow( display, win ); + return NULL; + } + else + return win; } @@ -843,9 +899,25 @@ XDestroyWindow( Display *display, Window w ) if (w == curDraw) { glXMakeCurrent( display, NULL, NULL); } - (*w->driDrawable.destroyDrawable)(display, w->driDrawable.private); + + /* Destroy the drawable. + */ + if (w->driDrawable.private) + (*w->driDrawable.destroyDrawable)(display, w->driDrawable.private); + + /* As this is done in CreateWindow, need to undo it here: + */ + if (display->driScreen.private) + (*display->driScreen.destroyScreen)(display, 0, + display->driScreen.private); + + /* As this is done in CreateWindow, need to undo it here: + */ + (*display->driverHaltFBDev)( display ); + /* put framebuffer back to initial state */ RestoreFBDev(display); + FREE(w); /* unlink window from display */ display->NumWindows--; diff --git a/src/miniglx/miniglxP.h b/src/miniglx/miniglxP.h index b666a99aa56..4989465704d 100644 --- a/src/miniglx/miniglxP.h +++ b/src/miniglx/miniglxP.h @@ -10,6 +10,7 @@ #ifndef _mini_GLX_client_h_ #define _mini_GLX_client_h_ +#include #include #include @@ -60,6 +61,7 @@ typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc, int numConfigs, __GLXvisualConfig *config); typedef void *(*InitFBDevFunc)( Display *dpy ); +typedef void *(*HaltFBDevFunc)( Display *dpy ); /** @@ -234,6 +236,7 @@ struct MiniGLXContextRec { struct MiniGLXDisplayRec { struct fb_fix_screeninfo FixedInfo; struct fb_var_screeninfo OrigVarInfo, VarInfo; + struct sigaction OrigSigUsr1; int DesiredDepth; int OriginalVT; int ConsoleFD; @@ -259,7 +262,6 @@ struct MiniGLXDisplayRec { * \name From __GLXdisplayPrivate */ /*@{*/ - InitFBDevFunc driverInitFBDev; CreateScreenFunc createScreen; __DRIscreen driScreen; void *dlHandle; /**< @@ -268,6 +270,13 @@ struct MiniGLXDisplayRec { */ /*@}*/ + /** + * \name New driver hooks + */ + /*@{*/ + InitFBDevFunc driverInitFBDev; + HaltFBDevFunc driverHaltFBDev; + /*@}*/ /** * \name Configuration details @@ -304,9 +313,9 @@ struct MiniGLXDisplayRec { * Populated by __driInitFBDev() */ /*@{*/ - void *driverPrivate; void *driverInfo; - int driverInfoSize; + void *driverClientMsg; + int driverClientMsgSize; /*@}*/ }; diff --git a/src/miniglx/xf86drm.h b/src/miniglx/xf86drm.h index 59595a211ae..e3278357b9a 100644 --- a/src/miniglx/xf86drm.h +++ b/src/miniglx/xf86drm.h @@ -404,6 +404,7 @@ do { register unsigned int __old __asm("o0"); \ #define DRM_LOCK(fd,lock,context,flags) \ do { \ + fprintf(stderr, "DRM_LOCK(%d,%p,%d) in %s\n",fd,lock,context, __FUNCTION__); \ if (flags) drmGetLock(fd,context,flags); \ else DRM_LIGHT_LOCK(fd,lock,context); \ } while(0) @@ -411,6 +412,7 @@ do { register unsigned int __old __asm("o0"); \ #define DRM_UNLOCK(fd,lock,context) \ do { \ DRM_CAS_RESULT(__ret); \ + fprintf(stderr, "DRM_UNLOCK in %s\n", __FUNCTION__); \ DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \ if (__ret) drmUnlock(fd,context); \ } while(0)