Exemple #1
0
/* The screen is being closed, so clean up any state and free any
   resources used by the DRI. */
void R128DRICloseScreen(const DRIDriverContext *ctx)
{
    R128InfoPtr info = ctx->driverPrivate;
    drm_r128_init_t drmInfo;

    /* Stop the CCE if it is still in use */
    R128CCE_STOP(ctx, info);

    if (info->irq) {
	drmCtlUninstHandler(ctx->drmFD);
	info->irq = 0;
    }

    /* De-allocate vertex buffers */
    if (info->buffers) {
	drmUnmapBufs(info->buffers);
	info->buffers = NULL;
    }

    /* De-allocate all kernel resources */
    memset(&drmInfo, 0, sizeof(drmInfo));
    drmInfo.func = R128_CLEANUP_CCE;
    drmCommandWrite(ctx->drmFD, DRM_R128_INIT,
                    &drmInfo, sizeof(drmInfo));

    /* De-allocate all AGP resources */
    if (info->agpTex) {
	drmUnmap(info->agpTex, info->agpTexMapSize);
	info->agpTex = NULL;
    }
    if (info->buf) {
	drmUnmap(info->buf, info->bufMapSize);
	info->buf = NULL;
    }
    if (info->ringReadPtr) {
	drmUnmap(info->ringReadPtr, info->ringReadMapSize);
	info->ringReadPtr = NULL;
    }
    if (info->ring) {
	drmUnmap(info->ring, info->ringMapSize);
	info->ring = NULL;
    }
    if (info->agpMemHandle != DRM_AGP_NO_HANDLE) {
	drmAgpUnbind(ctx->drmFD, info->agpMemHandle);
	drmAgpFree(ctx->drmFD, info->agpMemHandle);
	info->agpMemHandle = 0;
	drmAgpRelease(ctx->drmFD);
    }
    if (info->pciMemHandle) {
	drmScatterGatherFree(ctx->drmFD, info->pciMemHandle);
	info->pciMemHandle = 0;
    }
}
Exemple #2
0
/* Create the device specific screen private data struct.
 */
radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
{
   radeonScreenPtr radeonScreen;
   RADEONDRIPtr radeonDRIPriv = (RADEONDRIPtr)sPriv->pDevPriv;

   /* Check the DRI version */
   {
      int major, minor, patch;
      if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) {
         if ( major != 4 || minor < 0 ) {
            __driUtilMessage( "Radeon DRI driver expected DRI version 4.0.x "
			      "but got version %d.%d.%d",
			      major, minor, patch );
            return NULL;
         }
      }
   }

   /* Check that the DDX driver version is compatible */
   if ( sPriv->ddxMajor != 4 ||
	sPriv->ddxMinor < 0 ) {
      __driUtilMessage( "Radeon DRI driver expected DDX driver version 4.0.x "
			"but got version %d.%d.%d", 
			sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch );
      return NULL;
   }

   /* Check that the DRM driver version is compatible */
   /* KW:  Check minor number here too -- compatibility mode is broken
    * atm. 
    */
   if ( sPriv->drmMajor != 1 ||
	sPriv->drmMinor < 3) {
      __driUtilMessage( "Radeon DRI driver expected DRM driver version 1.3.x "
			"or newer but got version %d.%d.%d", 
			sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch );
      return NULL;
   }


   /* Allocate the private area */
   radeonScreen = (radeonScreenPtr) CALLOC( sizeof(*radeonScreen) );
   if ( !radeonScreen ) {
      __driUtilMessage("%s: CALLOC radeonScreen struct failed",
		       __FUNCTION__);
      return NULL;
   }

   if ( sPriv->drmMinor < 3 ||
        getenv("RADEON_COMPAT")) {
	   fprintf( stderr, "Radeon DRI driver:\n\t"
		    "Compatibility mode for DRM driver version %d.%d.%d\n\t"
		    "TCL will be disabled, expect reduced performance\n\t"
		    "(prefer DRM radeon.o 1.3.x or newer)\n\t", 
		    sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); 
   }


   /* This is first since which regions we map depends on whether or
    * not we are using a PCI card.
    */
   radeonScreen->IsPCI = radeonDRIPriv->IsPCI;

   if (sPriv->drmMinor >= 3) {
      int ret;
      drmRadeonGetParam gp;

      gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET;
      gp.value = &radeonScreen->agp_buffer_offset;

      ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
				 &gp, sizeof(gp));
      if (ret) {
	 FREE( radeonScreen );
	 fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret);
	 return NULL;
      }

      if (sPriv->drmMinor >= 6) {
	 gp.param = RADEON_PARAM_IRQ_NR;
	 gp.value = &radeonScreen->irq;

	 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
				    &gp, sizeof(gp));
	 if (ret) {
	    FREE( radeonScreen );
	    fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret);
	    return NULL;
	 }
      }

   }

   radeonScreen->mmio.handle = radeonDRIPriv->registerHandle;
   radeonScreen->mmio.size   = radeonDRIPriv->registerSize;
   if ( drmMap( sPriv->fd,
		radeonScreen->mmio.handle,
		radeonScreen->mmio.size,
		&radeonScreen->mmio.map ) ) {
      FREE( radeonScreen );
      __driUtilMessage("radeonCreateScreen(): drmMap failed\n");
      return NULL;
   }

   radeonScreen->status.handle = radeonDRIPriv->statusHandle;
   radeonScreen->status.size   = radeonDRIPriv->statusSize;
   if ( drmMap( sPriv->fd,
		radeonScreen->status.handle,
		radeonScreen->status.size,
		&radeonScreen->status.map ) ) {
      drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
      FREE( radeonScreen );
      __driUtilMessage("radeonCreateScreen(): drmMap (2) failed\n");
      return NULL;
   }
   radeonScreen->scratch = (__volatile__ CARD32 *)
      ((GLubyte *)radeonScreen->status.map + RADEON_SCRATCH_REG_OFFSET);

   radeonScreen->buffers = drmMapBufs( sPriv->fd );
   if ( !radeonScreen->buffers ) {
      drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
      drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
      FREE( radeonScreen );
      __driUtilMessage("radeonCreateScreen(): drmMapBufs failed\n");
      return NULL;
   }

   if ( !radeonScreen->IsPCI ) {
      radeonScreen->agpTextures.handle = radeonDRIPriv->agpTexHandle;
      radeonScreen->agpTextures.size   = radeonDRIPriv->agpTexMapSize;
      if ( drmMap( sPriv->fd,
		   radeonScreen->agpTextures.handle,
		   radeonScreen->agpTextures.size,
		   (drmAddressPtr)&radeonScreen->agpTextures.map ) ) {
	 drmUnmapBufs( radeonScreen->buffers );
	 drmUnmap( radeonScreen->status.map, radeonScreen->status.size );
	 drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size );
	 FREE( radeonScreen );
         __driUtilMessage("radeonCreateScreen(): IsPCI failed\n");
	 return NULL;
      }
   }

   radeonScreen->chipset = 0;
   switch ( radeonDRIPriv->deviceID ) {
   default:
      fprintf(stderr, "unknown chip id, assuming full radeon support\n");
   case PCI_CHIP_RADEON_QD:
   case PCI_CHIP_RADEON_QE:
   case PCI_CHIP_RADEON_QF:
   case PCI_CHIP_RADEON_QG:
   case PCI_CHIP_RV200_QW:
   case PCI_CHIP_RADEON_LW:
      radeonScreen->chipset |= RADEON_CHIPSET_TCL;
   case PCI_CHIP_RADEON_QY:
   case PCI_CHIP_RADEON_QZ:
   case PCI_CHIP_RADEON_LY:
   case PCI_CHIP_RADEON_LZ:
      break;
   }

   radeonScreen->cpp = radeonDRIPriv->bpp / 8;
   radeonScreen->AGPMode = radeonDRIPriv->AGPMode;

   radeonScreen->frontOffset	= radeonDRIPriv->frontOffset;
   radeonScreen->frontPitch	= radeonDRIPriv->frontPitch;
   radeonScreen->backOffset	= radeonDRIPriv->backOffset;
   radeonScreen->backPitch	= radeonDRIPriv->backPitch;
   radeonScreen->depthOffset	= radeonDRIPriv->depthOffset;
   radeonScreen->depthPitch	= radeonDRIPriv->depthPitch;

   radeonScreen->texOffset[RADEON_CARD_HEAP] = radeonDRIPriv->textureOffset;
   radeonScreen->texSize[RADEON_CARD_HEAP] = radeonDRIPriv->textureSize;
   radeonScreen->logTexGranularity[RADEON_CARD_HEAP] =
      radeonDRIPriv->log2TexGran;

   if ( radeonScreen->IsPCI ) {
      radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
      radeonScreen->texOffset[RADEON_AGP_HEAP] = 0;
      radeonScreen->texSize[RADEON_AGP_HEAP] = 0;
      radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = 0;
   } else {
      radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS;
      radeonScreen->texOffset[RADEON_AGP_HEAP] =
	 radeonDRIPriv->agpTexOffset + RADEON_AGP_TEX_OFFSET;
      radeonScreen->texSize[RADEON_AGP_HEAP] = radeonDRIPriv->agpTexMapSize;
      radeonScreen->logTexGranularity[RADEON_AGP_HEAP] =
	 radeonDRIPriv->log2AGPTexGran;
   }

   radeonScreen->driScreen = sPriv;
   radeonScreen->sarea_priv_offset = radeonDRIPriv->sarea_priv_offset;
   return radeonScreen;
}
/* Create the device specific screen private data struct.
 */
static mach64ScreenRec *
mach64CreateScreen( __DRIscreenPrivate *sPriv )
{
   mach64ScreenPtr mach64Screen;
   ATIDRIPtr serverInfo = (ATIDRIPtr)sPriv->pDevPriv;
   int i;

   if (sPriv->devPrivSize != sizeof(ATIDRIRec)) {
      fprintf(stderr,"\nERROR!  sizeof(ATIDRIRec) does not match passed size from device driver\n");
      return GL_FALSE;
   }

   if ( MACH64_DEBUG & DEBUG_VERBOSE_DRI ) 
      fprintf( stderr, "%s\n", __FUNCTION__ );

   /* Allocate the private area */
   mach64Screen = (mach64ScreenPtr) CALLOC( sizeof(*mach64Screen) );
   if ( !mach64Screen ) return NULL;

   /* parse information in __driConfigOptions */
   driParseOptionInfo (&mach64Screen->optionCache,
		       __driConfigOptions, __driNConfigOptions);

   mach64Screen->IsPCI = serverInfo->IsPCI;

   {
      drm_mach64_getparam_t gp;
      int ret;

      gp.param = MACH64_PARAM_IRQ_NR;
      gp.value = (void *) &mach64Screen->irq;

      ret = drmCommandWriteRead( sPriv->fd, DRM_MACH64_GETPARAM,
				    &gp, sizeof(gp));
      if (ret) {
         fprintf(stderr, "DRM_MACH64_GETPARAM (MACH64_PARAM_IRQ_NR): %d\n", ret);
         FREE( mach64Screen );
         return NULL;
      }
   }

   mach64Screen->mmio.handle = serverInfo->regs;
   mach64Screen->mmio.size   = serverInfo->regsSize;
   if ( drmMap( sPriv->fd,
		mach64Screen->mmio.handle,
		mach64Screen->mmio.size,
		(drmAddressPtr)&mach64Screen->mmio.map ) != 0 ) {
      FREE( mach64Screen );
      return NULL;
   }

   mach64Screen->buffers = drmMapBufs( sPriv->fd );
   if ( !mach64Screen->buffers ) {
      drmUnmap( (drmAddress)mach64Screen->mmio.map,
		mach64Screen->mmio.size );
      FREE( mach64Screen );
      return NULL;
   }

   if ( !mach64Screen->IsPCI ) {
      mach64Screen->agpTextures.handle = serverInfo->agp;
      mach64Screen->agpTextures.size   = serverInfo->agpSize;
      if ( drmMap( sPriv->fd,
		   mach64Screen->agpTextures.handle,
		   mach64Screen->agpTextures.size,
		   (drmAddressPtr)&mach64Screen->agpTextures.map ) ) {
	 drmUnmapBufs( mach64Screen->buffers );
	 drmUnmap( (drmAddress)mach64Screen->mmio.map, mach64Screen->mmio.size );
	 FREE( mach64Screen );
	 return NULL;
      }
   }

   mach64Screen->AGPMode	= serverInfo->AGPMode;

   mach64Screen->chipset	= serverInfo->chipset;
   mach64Screen->width		= serverInfo->width;
   mach64Screen->height		= serverInfo->height;
   mach64Screen->mem		= serverInfo->mem;
   mach64Screen->cpp		= serverInfo->cpp;

   mach64Screen->frontOffset	= serverInfo->frontOffset;
   mach64Screen->frontPitch	= serverInfo->frontPitch;
   mach64Screen->backOffset	= serverInfo->backOffset;
   mach64Screen->backPitch	= serverInfo->backPitch;
   mach64Screen->depthOffset	= serverInfo->depthOffset;
   mach64Screen->depthPitch	= serverInfo->depthPitch;

   mach64Screen->texOffset[MACH64_CARD_HEAP] = serverInfo->textureOffset;
   mach64Screen->texSize[MACH64_CARD_HEAP] = serverInfo->textureSize;
   mach64Screen->logTexGranularity[MACH64_CARD_HEAP] =
      serverInfo->logTextureGranularity;

   if ( mach64Screen->IsPCI ) {
      mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS - 1;
      mach64Screen->firstTexHeap = MACH64_CARD_HEAP;
      mach64Screen->texOffset[MACH64_AGP_HEAP] = 0;
      mach64Screen->texSize[MACH64_AGP_HEAP] = 0;
      mach64Screen->logTexGranularity[MACH64_AGP_HEAP] = 0;
   } else {
      if (serverInfo->textureSize > 0) {
	 mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS;
	 mach64Screen->firstTexHeap = MACH64_CARD_HEAP;
      } else {
	 mach64Screen->numTexHeaps = MACH64_NR_TEX_HEAPS - 1;
	 mach64Screen->firstTexHeap = MACH64_AGP_HEAP;
      }
      mach64Screen->texOffset[MACH64_AGP_HEAP] = serverInfo->agpTextureOffset;
      mach64Screen->texSize[MACH64_AGP_HEAP] = serverInfo->agpSize;
      mach64Screen->logTexGranularity[MACH64_AGP_HEAP] = serverInfo->logAgpTextureGranularity;
   }

   mach64Screen->driScreen = sPriv;

   i = 0;
   mach64Screen->extensions[i++] = &driFrameTrackingExtension.base;
   if ( mach64Screen->irq != 0 ) {
      mach64Screen->extensions[i++] = &driSwapControlExtension.base;
      mach64Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
   }
   mach64Screen->extensions[i++] = NULL;
   sPriv->extensions = mach64Screen->extensions;

   return mach64Screen;
}
Exemple #4
0
/* Create the device specific screen private data struct.
 */
static r128ScreenPtr
r128CreateScreen( __DRIscreen *sPriv )
{
    r128ScreenPtr r128Screen;
    R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
    int i;

    if (sPriv->devPrivSize != sizeof(R128DRIRec)) {
        fprintf(stderr,"\nERROR!  sizeof(R128DRIRec) does not match passed size from device driver\n");
        return GL_FALSE;
    }

    /* Allocate the private area */
    r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) );
    if ( !r128Screen ) return NULL;

    /* parse information in __driConfigOptions */
    driParseOptionInfo (&r128Screen->optionCache,
                        __driConfigOptions, __driNConfigOptions);

    /* This is first since which regions we map depends on whether or
     * not we are using a PCI card.
     */
    r128Screen->IsPCI = r128DRIPriv->IsPCI;
    r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset;

    if (sPriv->drm_version.minor >= 3) {
        drm_r128_getparam_t gp;
        int ret;

        gp.param = R128_PARAM_IRQ_NR;
        gp.value = &r128Screen->irq;

        ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM,
                                   &gp, sizeof(gp));
        if (ret) {
            fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret);
            FREE( r128Screen );
            return NULL;
        }
    }

    r128Screen->mmio.handle = r128DRIPriv->registerHandle;
    r128Screen->mmio.size   = r128DRIPriv->registerSize;
    if ( drmMap( sPriv->fd,
                 r128Screen->mmio.handle,
                 r128Screen->mmio.size,
                 (drmAddressPtr)&r128Screen->mmio.map ) ) {
        FREE( r128Screen );
        return NULL;
    }

    r128Screen->buffers = drmMapBufs( sPriv->fd );
    if ( !r128Screen->buffers ) {
        drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
        FREE( r128Screen );
        return NULL;
    }

    if ( !r128Screen->IsPCI ) {
        r128Screen->agpTextures.handle = r128DRIPriv->agpTexHandle;
        r128Screen->agpTextures.size   = r128DRIPriv->agpTexMapSize;
        if ( drmMap( sPriv->fd,
                     r128Screen->agpTextures.handle,
                     r128Screen->agpTextures.size,
                     (drmAddressPtr)&r128Screen->agpTextures.map ) ) {
            drmUnmapBufs( r128Screen->buffers );
            drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
            FREE( r128Screen );
            return NULL;
        }
    }

    switch ( r128DRIPriv->deviceID ) {
    case PCI_CHIP_RAGE128RE:
    case PCI_CHIP_RAGE128RF:
    case PCI_CHIP_RAGE128RK:
    case PCI_CHIP_RAGE128RL:
        r128Screen->chipset = R128_CARD_TYPE_R128;
        break;
    case PCI_CHIP_RAGE128PF:
        r128Screen->chipset = R128_CARD_TYPE_R128_PRO;
        break;
    case PCI_CHIP_RAGE128LE:
    case PCI_CHIP_RAGE128LF:
        r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY;
        break;
    default:
        r128Screen->chipset = R128_CARD_TYPE_R128;
        break;
    }

    r128Screen->cpp = r128DRIPriv->bpp / 8;
    r128Screen->AGPMode = r128DRIPriv->AGPMode;

    r128Screen->frontOffset	= r128DRIPriv->frontOffset;
    r128Screen->frontPitch	= r128DRIPriv->frontPitch;
    r128Screen->backOffset	= r128DRIPriv->backOffset;
    r128Screen->backPitch	= r128DRIPriv->backPitch;
    r128Screen->depthOffset	= r128DRIPriv->depthOffset;
    r128Screen->depthPitch	= r128DRIPriv->depthPitch;
    r128Screen->spanOffset	= r128DRIPriv->spanOffset;

    if ( r128DRIPriv->textureSize == 0 ) {
        r128Screen->texOffset[R128_LOCAL_TEX_HEAP] =
            r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
        r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->agpTexMapSize;
        r128Screen->logTexGranularity[R128_LOCAL_TEX_HEAP] =
            r128DRIPriv->log2AGPTexGran;
    } else {
        r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureOffset;
        r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize;
        r128Screen->logTexGranularity[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran;
    }

    if ( !r128Screen->agpTextures.map || r128DRIPriv->textureSize == 0 ) {
        r128Screen->numTexHeaps = R128_NR_TEX_HEAPS - 1;
        r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
        r128Screen->texSize[R128_AGP_TEX_HEAP] = 0;
        r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] = 0;
    } else {
        r128Screen->numTexHeaps = R128_NR_TEX_HEAPS;
        r128Screen->texOffset[R128_AGP_TEX_HEAP] =
            r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
        r128Screen->texSize[R128_AGP_TEX_HEAP] = r128DRIPriv->agpTexMapSize;
        r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] =
            r128DRIPriv->log2AGPTexGran;
    }

    r128Screen->driScreen = sPriv;

    i = 0;
    r128Screen->extensions[i++] = &driFrameTrackingExtension.base;
    if ( r128Screen->irq != 0 ) {
        r128Screen->extensions[i++] = &driSwapControlExtension.base;
        r128Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
    }
    r128Screen->extensions[i++] = NULL;
    sPriv->extensions = r128Screen->extensions;

    return r128Screen;
}
Exemple #5
0
/* Create the device specific screen private data struct.
 */
static r128ScreenPtr
r128CreateScreen( __DRIscreenPrivate *sPriv )
{
   r128ScreenPtr r128Screen;
   R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
   PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
     (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
   void * const psc = sPriv->psc->screenConfigs;

   if (sPriv->devPrivSize != sizeof(R128DRIRec)) {
      fprintf(stderr,"\nERROR!  sizeof(R128DRIRec) does not match passed size from device driver\n");
      return GL_FALSE;
   }

   /* Allocate the private area */
   r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) );
   if ( !r128Screen ) return NULL;

   /* parse information in __driConfigOptions */
   driParseOptionInfo (&r128Screen->optionCache,
		       __driConfigOptions, __driNConfigOptions);

   /* This is first since which regions we map depends on whether or
    * not we are using a PCI card.
    */
   r128Screen->IsPCI = r128DRIPriv->IsPCI;
   r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset;
   
   if (sPriv->drmMinor >= 3) {
      drm_r128_getparam_t gp;
      int ret;

      gp.param = R128_PARAM_IRQ_NR;
      gp.value = &r128Screen->irq;

      ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM,
				    &gp, sizeof(gp));
      if (ret) {
         fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret);
         FREE( r128Screen );
         return NULL;
      }
   }

   r128Screen->mmio.handle = r128DRIPriv->registerHandle;
   r128Screen->mmio.size   = r128DRIPriv->registerSize;
   if ( drmMap( sPriv->fd,
		r128Screen->mmio.handle,
		r128Screen->mmio.size,
		(drmAddressPtr)&r128Screen->mmio.map ) ) {
      FREE( r128Screen );
      return NULL;
   }

   r128Screen->buffers = drmMapBufs( sPriv->fd );
   if ( !r128Screen->buffers ) {
      drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
      FREE( r128Screen );
      return NULL;
   }

   if ( !r128Screen->IsPCI ) {
      r128Screen->agpTextures.handle = r128DRIPriv->agpTexHandle;
      r128Screen->agpTextures.size   = r128DRIPriv->agpTexMapSize;
      if ( drmMap( sPriv->fd,
		   r128Screen->agpTextures.handle,
		   r128Screen->agpTextures.size,
		   (drmAddressPtr)&r128Screen->agpTextures.map ) ) {
	 drmUnmapBufs( r128Screen->buffers );
	 drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
	 FREE( r128Screen );
	 return NULL;
      }
   }

   switch ( r128DRIPriv->deviceID ) {
   case PCI_CHIP_RAGE128RE:
   case PCI_CHIP_RAGE128RF:
   case PCI_CHIP_RAGE128RK:
   case PCI_CHIP_RAGE128RL:
      r128Screen->chipset = R128_CARD_TYPE_R128;
      break;
   case PCI_CHIP_RAGE128PF:
      r128Screen->chipset = R128_CARD_TYPE_R128_PRO;
      break;
   case PCI_CHIP_RAGE128LE:
   case PCI_CHIP_RAGE128LF:
      r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY;
      break;
   default:
      r128Screen->chipset = R128_CARD_TYPE_R128;
      break;
   }

   r128Screen->cpp = r128DRIPriv->bpp / 8;
   r128Screen->AGPMode = r128DRIPriv->AGPMode;

   r128Screen->frontOffset	= r128DRIPriv->frontOffset;
   r128Screen->frontPitch	= r128DRIPriv->frontPitch;
   r128Screen->backOffset	= r128DRIPriv->backOffset;
   r128Screen->backPitch	= r128DRIPriv->backPitch;
   r128Screen->depthOffset	= r128DRIPriv->depthOffset;
   r128Screen->depthPitch	= r128DRIPriv->depthPitch;
   r128Screen->spanOffset	= r128DRIPriv->spanOffset;

   if ( r128DRIPriv->textureSize == 0 ) {
      r128Screen->texOffset[R128_LOCAL_TEX_HEAP] =
	 r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
      r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->agpTexMapSize;
      r128Screen->logTexGranularity[R128_LOCAL_TEX_HEAP] =
	 r128DRIPriv->log2AGPTexGran;
   } else {
      r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureOffset;
      r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize;
      r128Screen->logTexGranularity[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran;
   }

   if ( !r128Screen->agpTextures.map || r128DRIPriv->textureSize == 0 ) {
      r128Screen->numTexHeaps = R128_NR_TEX_HEAPS - 1;
      r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0;
      r128Screen->texSize[R128_AGP_TEX_HEAP] = 0;
      r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] = 0;
   } else {
      r128Screen->numTexHeaps = R128_NR_TEX_HEAPS;
      r128Screen->texOffset[R128_AGP_TEX_HEAP] =
	 r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
      r128Screen->texSize[R128_AGP_TEX_HEAP] = r128DRIPriv->agpTexMapSize;
      r128Screen->logTexGranularity[R128_AGP_TEX_HEAP] =
	 r128DRIPriv->log2AGPTexGran;
   }

   r128Screen->driScreen = sPriv;

   if ( glx_enable_extension != NULL ) {
      if ( r128Screen->irq != 0 ) {
	 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
	 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
	 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
      }

      (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
   }

   return r128Screen;
}