/* 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; }
gammaScreenPtr gammaCreateScreen( __DRIscreenPrivate *sPriv ) { gammaScreenPtr gammaScreen; GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)sPriv->pDevPriv; int i; if (sPriv->devPrivSize != sizeof(GLINTDRIRec)) { fprintf(stderr,"\nERROR! sizeof(GLINTDRIRec) does not match passed size from device driver\n"); return GL_FALSE; } #if 0 /* Check the DRI externsion version */ if ( sPriv->driMajor != 3 || sPriv->driMinor != 1 ) { __driUtilMessage( "Gamma DRI driver expected DRI version 4.0.x " "but got version %d.%d.%d", sPriv->driMajor, sPriv->driMinor, sPriv->driPatch ); return NULL; } /* Check that the DDX driver version is compatible */ if ( sPriv->ddxMajor != 4 || sPriv->ddxMinor != 0 || sPriv->ddxPatch < 0 ) { __driUtilMessage( "r128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); return GL_FALSE; } /* Check that the DRM driver version is compatible */ if ( sPriv->drmMajor != 2 || sPriv->drmMinor != 1 || sPriv->drmPatch < 0 ) { __driUtilMessage( "r128 DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); return GL_FALSE; } #endif /* Allocate the private area */ gammaScreen = (gammaScreenPtr) CALLOC( sizeof(*gammaScreen) ); if ( !gammaScreen ) return NULL; gammaScreen->regionCount = 4; /* Magic number. Can we fix this? */ gammaScreen->regions = CALLOC(gammaScreen->regionCount * sizeof(gammaRegion)); gammaScreen->regions[0].handle = gDRIPriv->registers0.handle; gammaScreen->regions[0].size = gDRIPriv->registers0.size; gammaScreen->regions[1].handle = gDRIPriv->registers1.handle; gammaScreen->regions[1].size = gDRIPriv->registers1.size; gammaScreen->regions[2].handle = gDRIPriv->registers2.handle; gammaScreen->regions[2].size = gDRIPriv->registers2.size; gammaScreen->regions[3].handle = gDRIPriv->registers3.handle; gammaScreen->regions[3].size = gDRIPriv->registers3.size; /* Next, map all the regions */ for (i = 0; i < gammaScreen->regionCount; i++) { if (drmMap(sPriv->fd, gammaScreen->regions[i].handle, gammaScreen->regions[i].size, &gammaScreen->regions[i].map)) { while (--i > 0) { (void)drmUnmap(gammaScreen->regions[i].map, gammaScreen->regions[i].size); } return GL_FALSE; } } /* Get the list of dma buffers */ gammaScreen->bufs = drmMapBufs(sPriv->fd); if (!gammaScreen->bufs) { while (gammaScreen->regionCount > 0) { (void)drmUnmap(gammaScreen->regions[gammaScreen->regionCount].map, gammaScreen->regions[gammaScreen->regionCount].size); gammaScreen->regionCount--; } return GL_FALSE; } gammaScreen->textureSize = gDRIPriv->textureSize; gammaScreen->logTextureGranularity = gDRIPriv->logTextureGranularity; gammaScreen->cpp = gDRIPriv->cpp; gammaScreen->frontOffset = gDRIPriv->frontOffset; gammaScreen->frontPitch = gDRIPriv->frontPitch; gammaScreen->backOffset = gDRIPriv->backOffset; gammaScreen->backPitch = gDRIPriv->backPitch; gammaScreen->backX = gDRIPriv->backX; gammaScreen->backY = gDRIPriv->backY; gammaScreen->depthOffset = gDRIPriv->depthOffset; gammaScreen->depthPitch = gDRIPriv->depthPitch; gammaScreen->driScreen = sPriv; return gammaScreen; }
/** * Perform the required libGL-side initialization and call the client-side * driver's \c __driCreateNewScreen function. * * \param dpy Display pointer. * \param scrn Screen number on the display. * \param psc DRI screen information. * \param driDpy DRI display information. * \param createNewScreen Pointer to the client-side driver's * \c __driCreateNewScreen function. * \returns A pointer to the \c __DRIscreenPrivate structure returned by * the client-side driver on success, or \c NULL on failure. */ static void * CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, __GLXDRIdisplayPrivate * driDpy) { void *psp = NULL; drm_handle_t hSAREA; drmAddress pSAREA = MAP_FAILED; char *BusID; __DRIversion ddx_version; __DRIversion dri_version; __DRIversion drm_version; __DRIframebuffer framebuffer; int fd = -1; int status; drm_magic_t magic; drmVersionPtr version; int newlyopened; char *driverName; drm_handle_t hFB; int junk; const __DRIconfig **driver_configs; __GLcontextModes *visual; /* DRI protocol version. */ dri_version.major = driDpy->driMajor; dri_version.minor = driDpy->driMinor; dri_version.patch = driDpy->driPatch; framebuffer.base = MAP_FAILED; framebuffer.dev_priv = NULL; if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { ErrorMessageF("XF86DRIOpenConnection failed\n"); goto handle_error; } fd = drmOpenOnce(NULL, BusID, &newlyopened); Xfree(BusID); /* No longer needed */ if (fd < 0) { ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd)); goto handle_error; } if (drmGetMagic(fd, &magic)) { ErrorMessageF("drmGetMagic failed\n"); goto handle_error; } version = drmGetVersion(fd); if (version) { drm_version.major = version->version_major; drm_version.minor = version->version_minor; drm_version.patch = version->version_patchlevel; drmFreeVersion(version); } else { drm_version.major = -1; drm_version.minor = -1; drm_version.patch = -1; } if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) { ErrorMessageF("XF86DRIAuthConnection failed\n"); goto handle_error; } /* Get device name (like "tdfx") and the ddx version numbers. * We'll check the version in each DRI driver's "createNewScreen" * function. */ if (!XF86DRIGetClientDriverName(dpy, scrn, &ddx_version.major, &ddx_version.minor, &ddx_version.patch, &driverName)) { ErrorMessageF("XF86DRIGetClientDriverName failed\n"); goto handle_error; } Xfree(driverName); /* No longer needed. */ /* * Get device-specific info. pDevPriv will point to a struct * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that * has information about the screen size, depth, pitch, ancilliary * buffers, DRM mmap handles, etc. */ if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk, &framebuffer.size, &framebuffer.stride, &framebuffer.dev_priv_size, &framebuffer.dev_priv)) { ErrorMessageF("XF86DRIGetDeviceInfo failed"); goto handle_error; } framebuffer.width = DisplayWidth(dpy, scrn); framebuffer.height = DisplayHeight(dpy, scrn); /* Map the framebuffer region. */ status = drmMap(fd, hFB, framebuffer.size, (drmAddressPtr)&framebuffer.base); if (status != 0) { ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status)); goto handle_error; } /* Map the SAREA region. Further mmap regions may be setup in * each DRI driver's "createNewScreen" function. */ status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA); if (status != 0) { ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status)); goto handle_error; } psp = (*psc->legacy->createNewScreen)(scrn, &ddx_version, &dri_version, &drm_version, &framebuffer, pSAREA, fd, loader_extensions, &driver_configs, psc); if (psp == NULL) { ErrorMessageF("Calling driver entry point failed"); goto handle_error; } psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); psc->driver_configs = driver_configs; /* Visuals with depth != screen depth are subject to automatic compositing * in the X server, so DRI1 can't render to them properly. Mark them as * non-conformant to prevent apps from picking them up accidentally. */ for (visual = psc->visuals; visual; visual = visual->next) { XVisualInfo template;
/* 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; }
/* 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; }
/* Initialize the screen-specific data structures for the DRI and the Rage 128. This is the main entry point to the device-specific initialization code. It calls device-independent DRI functions to create the DRI data structures and initialize the DRI state. */ static GLboolean R128DRIScreenInit(DRIDriverContext *ctx) { R128InfoPtr info = ctx->driverPrivate; R128DRIPtr pR128DRI; int err, major, minor, patch; drmVersionPtr version; drm_r128_sarea_t *pSAREAPriv; switch (ctx->bpp) { case 8: /* These modes are not supported (yet). */ case 15: case 24: fprintf(stderr, "[dri] R128DRIScreenInit failed (depth %d not supported). " "[dri] Disabling DRI.\n", ctx->bpp); return GL_FALSE; /* Only 16 and 32 color depths are supports currently. */ case 16: case 32: break; } r128_drm_page_size = getpagesize(); info->registerSize = ctx->MMIOSize; ctx->shared.SAREASize = SAREA_MAX; /* Note that drmOpen will try to load the kernel module, if needed. */ ctx->drmFD = drmOpen("r128", NULL ); if (ctx->drmFD < 0) { fprintf(stderr, "[drm] drmOpen failed\n"); return 0; } /* Check the r128 DRM version */ version = drmGetVersion(ctx->drmFD); if (version) { if (version->version_major != 2 || version->version_minor < 2) { /* incompatible drm version */ fprintf(stderr, "[dri] R128DRIScreenInit failed because of a version mismatch.\n" "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n" "[dri] Disabling the DRI.\n", version->version_major, version->version_minor, version->version_patchlevel); drmFreeVersion(version); return GL_FALSE; } info->drmMinor = version->version_minor; drmFreeVersion(version); } if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", ctx->drmFD, ctx->pciBusID, strerror(-err)); return 0; } if (drmAddMap( ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM, DRM_CONTAINS_LOCK, &ctx->shared.hSAREA) < 0) { fprintf(stderr, "[drm] drmAddMap failed\n"); return 0; } fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", ctx->shared.SAREASize, ctx->shared.hSAREA); if (drmMap( ctx->drmFD, ctx->shared.hSAREA, ctx->shared.SAREASize, (drmAddressPtr)(&ctx->pSAREA)) < 0) { fprintf(stderr, "[drm] drmMap failed\n"); return 0; } memset(ctx->pSAREA, 0, ctx->shared.SAREASize); fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); /* Need to AddMap the framebuffer and mmio regions here: */ if (drmAddMap( ctx->drmFD, (drm_handle_t)ctx->FBStart, ctx->FBSize, DRM_FRAME_BUFFER, 0, &ctx->shared.hFrameBuffer) < 0) { fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); return 0; } fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", ctx->shared.hFrameBuffer); if (!R128MemoryInit(ctx)) return GL_FALSE; /* Initialize AGP */ if (!info->IsPCI && !R128DRIAgpInit(ctx)) { info->IsPCI = GL_TRUE; fprintf(stderr, "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); fprintf(stderr, "[agp] Make sure you have the agpgart kernel module loaded.\n"); } /* Initialize PCIGART */ if (info->IsPCI && !R128DRIPciInit(ctx)) { return GL_FALSE; } /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */ if (!R128DRIMapInit(ctx)) { return GL_FALSE; } /* Create a 'server' context so we can grab the lock for * initialization ioctls. */ if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); return 0; } DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); /* Initialize the kernel data structures */ if (!R128DRIKernelInit(ctx)) { return GL_FALSE; } /* Initialize the vertex buffers list */ if (!R128DRIBufInit(ctx)) { return GL_FALSE; } /* Initialize IRQ */ R128DRIIrqInit(ctx); /* Initialize and start the CCE if required */ R128DRICCEInit(ctx); /* Quick hack to clear the front & back buffers. Could also use * the clear ioctl to do this, but would need to setup hw state * first. */ drimemsetio((char *)ctx->FBAddress + info->frontOffset, 0, info->frontPitch * ctx->cpp * ctx->shared.virtualHeight ); drimemsetio((char *)ctx->FBAddress + info->backOffset, 0, info->backPitch * ctx->cpp * ctx->shared.virtualHeight ); pSAREAPriv = (drm_r128_sarea_t *)(((char*)ctx->pSAREA) + sizeof(drm_sarea_t)); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); /* This is the struct passed to radeon_dri.so for its initialization */ ctx->driverClientMsg = malloc(sizeof(R128DRIRec)); ctx->driverClientMsgSize = sizeof(R128DRIRec); pR128DRI = (R128DRIPtr)ctx->driverClientMsg; pR128DRI->deviceID = info->Chipset; pR128DRI->width = ctx->shared.virtualWidth; pR128DRI->height = ctx->shared.virtualHeight; pR128DRI->depth = ctx->bpp; pR128DRI->bpp = ctx->bpp; pR128DRI->IsPCI = info->IsPCI; pR128DRI->AGPMode = info->agpMode; pR128DRI->frontOffset = info->frontOffset; pR128DRI->frontPitch = info->frontPitch; pR128DRI->backOffset = info->backOffset; pR128DRI->backPitch = info->backPitch; pR128DRI->depthOffset = info->depthOffset; pR128DRI->depthPitch = info->depthPitch; pR128DRI->spanOffset = info->spanOffset; pR128DRI->textureOffset = info->textureOffset; pR128DRI->textureSize = info->textureSize; pR128DRI->log2TexGran = info->log2TexGran; pR128DRI->registerHandle = info->registerHandle; pR128DRI->registerSize = info->registerSize; pR128DRI->agpTexHandle = info->agpTexHandle; pR128DRI->agpTexMapSize = info->agpTexMapSize; pR128DRI->log2AGPTexGran = info->log2AGPTexGran; pR128DRI->agpTexOffset = info->agpTexStart; pR128DRI->sarea_priv_offset = sizeof(drm_sarea_t); return GL_TRUE; }
/* Initialize the AGP state. Request memory for use in AGP space, and initialize the Rage 128 registers to point to that memory. */ static GLboolean R128DRIAgpInit(const DRIDriverContext *ctx) { unsigned char *R128MMIO = ctx->MMIOAddress; R128InfoPtr info = ctx->driverPrivate; unsigned long mode; unsigned int vendor, device; int ret; unsigned long cntl, chunk; int s, l; int flags; unsigned long agpBase; if (drmAgpAcquire(ctx->drmFD) < 0) { fprintf(stderr, "[agp] AGP not available\n"); return GL_FALSE; } /* Modify the mode if the default mode is not appropriate for this particular combination of graphics card and AGP chipset. */ mode = drmAgpGetMode(ctx->drmFD); /* Default mode */ vendor = drmAgpVendorId(ctx->drmFD); device = drmAgpDeviceId(ctx->drmFD); mode &= ~R128_AGP_MODE_MASK; switch (info->agpMode) { case 4: mode |= R128_AGP_4X_MODE; case 2: mode |= R128_AGP_2X_MODE; case 1: default: mode |= R128_AGP_1X_MODE; } fprintf(stderr, "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", mode, vendor, device, 0x1002, info->Chipset); if (drmAgpEnable(ctx->drmFD, mode) < 0) { fprintf(stderr, "[agp] AGP not enabled\n"); drmAgpRelease(ctx->drmFD); return GL_FALSE; } info->agpOffset = 0; if ((ret = drmAgpAlloc(ctx->drmFD, info->agpSize*1024*1024, 0, NULL, &info->agpMemHandle)) < 0) { fprintf(stderr, "[agp] Out of memory (%d)\n", ret); drmAgpRelease(ctx->drmFD); return GL_FALSE; } fprintf(stderr, "[agp] %d kB allocated with handle 0x%08x\n", info->agpSize*1024, info->agpMemHandle); if (drmAgpBind(ctx->drmFD, info->agpMemHandle, info->agpOffset) < 0) { fprintf(stderr, "[agp] Could not bind\n"); drmAgpFree(ctx->drmFD, info->agpMemHandle); drmAgpRelease(ctx->drmFD); return GL_FALSE; } /* Initialize the CCE ring buffer data */ info->ringStart = info->agpOffset; info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; info->ringReadOffset = info->ringStart + info->ringMapSize; info->ringReadMapSize = r128_drm_page_size; /* Reserve space for vertex/indirect buffers */ info->bufStart = info->ringReadOffset + info->ringReadMapSize; info->bufMapSize = info->bufSize*1024*1024; /* Reserve the rest for AGP textures */ info->agpTexStart = info->bufStart + info->bufMapSize; s = (info->agpSize*1024*1024 - info->agpTexStart); l = R128MinBits((s-1) / R128_NR_TEX_REGIONS); if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; info->agpTexMapSize = (s >> l) << l; info->log2AGPTexGran = l; if (info->CCESecure) flags = DRM_READ_ONLY; else flags = 0; if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, DRM_AGP, flags, &info->ringHandle) < 0) { fprintf(stderr, "[agp] Could not add ring mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] ring handle = 0x%08x\n", info->ringHandle); if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, (drmAddressPtr)&info->ring) < 0) { fprintf(stderr, "[agp] Could not map ring\n"); return GL_FALSE; } fprintf(stderr, "[agp] Ring mapped at 0x%08lx\n", (unsigned long)info->ring); if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, DRM_AGP, flags, &info->ringReadPtrHandle) < 0) { fprintf(stderr, "[agp] Could not add ring read ptr mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] ring read ptr handle = 0x%08x\n", info->ringReadPtrHandle); if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, (drmAddressPtr)&info->ringReadPtr) < 0) { fprintf(stderr, "[agp] Could not map ring read ptr\n"); return GL_FALSE; } fprintf(stderr, "[agp] Ring read ptr mapped at 0x%08lx\n", (unsigned long)info->ringReadPtr); if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, DRM_AGP, 0, &info->bufHandle) < 0) { fprintf(stderr, "[agp] Could not add vertex/indirect buffers mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] vertex/indirect buffers handle = 0x%08lx\n", info->bufHandle); if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, (drmAddressPtr)&info->buf) < 0) { fprintf(stderr, "[agp] Could not map vertex/indirect buffers\n"); return GL_FALSE; } fprintf(stderr, "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", (unsigned long)info->buf); if (drmAddMap(ctx->drmFD, info->agpTexStart, info->agpTexMapSize, DRM_AGP, 0, &info->agpTexHandle) < 0) { fprintf(stderr, "[agp] Could not add AGP texture map mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] AGP texture map handle = 0x%08lx\n", info->agpTexHandle); if (drmMap(ctx->drmFD, info->agpTexHandle, info->agpTexMapSize, (drmAddressPtr)&info->agpTex) < 0) { fprintf(stderr, "[agp] Could not map AGP texture map\n"); return GL_FALSE; } fprintf(stderr, "[agp] AGP Texture map mapped at 0x%08lx\n", (unsigned long)info->agpTex); /* Initialize Rage 128's AGP registers */ cntl = INREG(R128_AGP_CNTL); cntl &= ~R128_AGP_APER_SIZE_MASK; switch (info->agpSize) { case 256: cntl |= R128_AGP_APER_SIZE_256MB; break; case 128: cntl |= R128_AGP_APER_SIZE_128MB; break; case 64: cntl |= R128_AGP_APER_SIZE_64MB; break; case 32: cntl |= R128_AGP_APER_SIZE_32MB; break; case 16: cntl |= R128_AGP_APER_SIZE_16MB; break; case 8: cntl |= R128_AGP_APER_SIZE_8MB; break; case 4: cntl |= R128_AGP_APER_SIZE_4MB; break; default: fprintf(stderr, "[agp] Illegal aperture size %d kB\n", info->agpSize*1024); return GL_FALSE; } agpBase = drmAgpBase(ctx->drmFD); OUTREG(R128_AGP_BASE, agpBase); OUTREG(R128_AGP_CNTL, cntl); /* Disable Rage 128's PCIGART registers */ chunk = INREG(R128_BM_CHUNK_0_VAL); chunk &= ~(R128_BM_PTR_FORCE_TO_PCI | R128_BM_PM4_RD_FORCE_TO_PCI | R128_BM_GLOBAL_FORCE_TO_PCI); OUTREG(R128_BM_CHUNK_0_VAL, chunk); OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */ return GL_TRUE; }
static GLboolean R128DRIPciInit(const DRIDriverContext *ctx) { R128InfoPtr info = ctx->driverPrivate; unsigned char *R128MMIO = ctx->MMIOAddress; u_int32_t chunk; int ret; int flags; info->agpOffset = 0; ret = drmScatterGatherAlloc(ctx->drmFD, info->agpSize*1024*1024, &info->pciMemHandle); if (ret < 0) { fprintf(stderr, "[pci] Out of memory (%d)\n", ret); return GL_FALSE; } fprintf(stderr, "[pci] %d kB allocated with handle 0x%08x\n", info->agpSize*1024, info->pciMemHandle); /* Initialize the CCE ring buffer data */ info->ringStart = info->agpOffset; info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; info->ringReadOffset = info->ringStart + info->ringMapSize; info->ringReadMapSize = r128_drm_page_size; /* Reserve space for vertex/indirect buffers */ info->bufStart = info->ringReadOffset + info->ringReadMapSize; info->bufMapSize = info->bufSize*1024*1024; flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { fprintf(stderr, "[pci] Could not add ring mapping\n"); return GL_FALSE; } fprintf(stderr, "[pci] ring handle = 0x%08lx\n", info->ringHandle); if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, (drmAddressPtr)&info->ring) < 0) { fprintf(stderr, "[pci] Could not map ring\n"); return GL_FALSE; } fprintf(stderr, "[pci] Ring mapped at 0x%08lx\n", (unsigned long)info->ring); fprintf(stderr, "[pci] Ring contents 0x%08lx\n", *(unsigned long *)info->ring); if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { fprintf(stderr, "[pci] Could not add ring read ptr mapping\n"); return GL_FALSE; } fprintf(stderr, "[pci] ring read ptr handle = 0x%08lx\n", info->ringReadPtrHandle); if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, (drmAddressPtr)&info->ringReadPtr) < 0) { fprintf(stderr, "[pci] Could not map ring read ptr\n"); return GL_FALSE; } fprintf(stderr, "[pci] Ring read ptr mapped at 0x%08lx\n", (unsigned long)info->ringReadPtr); fprintf(stderr, "[pci] Ring read ptr contents 0x%08lx\n", *(unsigned long *)info->ringReadPtr); if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { fprintf(stderr, "[pci] Could not add vertex/indirect buffers mapping\n"); return GL_FALSE; } fprintf(stderr, "[pci] vertex/indirect buffers handle = 0x%08lx\n", info->bufHandle); if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, (drmAddressPtr)&info->buf) < 0) { fprintf(stderr, "[pci] Could not map vertex/indirect buffers\n"); return GL_FALSE; } fprintf(stderr, "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", (unsigned long)info->buf); fprintf(stderr, "[pci] Vertex/indirect buffers contents 0x%08lx\n", *(unsigned long *)info->buf); if (!info->IsPCI) { /* This is really an AGP card, force PCI GART mode */ chunk = INREG(R128_BM_CHUNK_0_VAL); chunk |= (R128_BM_PTR_FORCE_TO_PCI | R128_BM_PM4_RD_FORCE_TO_PCI | R128_BM_GLOBAL_FORCE_TO_PCI); OUTREG(R128_BM_CHUNK_0_VAL, chunk); OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ } return GL_TRUE; }
int main(int argc, char **argv) { int c; int r = 0; int fd = -1; drm_handle_t handle; void *address; char *pt; unsigned long count; unsigned long offset; unsigned long size; drm_context_t context; int loops; char buf[1024]; int i; drmBufInfoPtr info; drmBufMapPtr bufs; drmLockPtr lock; int secs; while ((c = getopt(argc, argv, "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF) switch (c) { case 'F': count = strtoul(optarg, NULL, 0); if (!fork()) { dup(fd); sleep(count); } close(fd); break; case 'v': getversion(fd); break; case 'X': if ((r = drmCreateContext(fd, &context))) { drmError(r, argv[0]); return 1; } printf( "Got %d\n", context); break; case 'S': process_sigio(optarg); break; case 'C': if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) { drmError(r, argv[0]); return 1; } break; case 'c': if ((r = drmSetBusid(fd,optarg))) { drmError(r, argv[0]); return 1; } break; case 'o': if ((fd = drmOpen(optarg, NULL)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'O': if ((fd = drmOpen(NULL, optarg)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'B': /* Test buffer allocation */ count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, &pt, 0); secs = strtoul(pt+1, NULL, 0); { drmDMAReq dma; int *indices, *sizes; indices = alloca(sizeof(*indices) * count); sizes = alloca(sizeof(*sizes) * count); dma.context = context; dma.send_count = 0; dma.request_count = count; dma.request_size = size; dma.request_list = indices; dma.request_sizes = sizes; dma.flags = DRM_DMA_WAIT; if ((r = drmDMA(fd, &dma))) { drmError(r, argv[0]); return 1; } for (i = 0; i < dma.granted_count; i++) { printf("%5d: index = %d, size = %d\n", i, dma.request_list[i], dma.request_sizes[i]); } sleep(secs); drmFreeBufs(fd, dma.granted_count, indices); } break; case 'b': count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } if ((r = drmMarkBufs(fd, 0.50, 0.80))) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); #if 1 if (!(bufs = drmMapBufs(fd))) { drmError(0, argv[0]); return 1; } printf("===============================\n"); printf( "%d bufs\n", bufs->count); for (i = 0; i < bufs->count; i++) { printf( " %4d: %8d bytes at %p\n", i, bufs->list[i].total, bufs->list[i].address); } printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); #endif break; case 'f': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_FRAME_BUFFER, 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); break; case 'r': case 'R': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_REGISTERS, c == 'R' ? DRM_READ_ONLY : 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); break; case 's': size = strtoul(optarg, &pt, 0); handle = 0; if ((r = drmAddMap(fd, 0, size, DRM_SHM, DRM_CONTAINS_LOCK, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%04lx byte shm added at 0x%08lx\n", size, handle); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vm"); system(buf); break; case 'P': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx mapped at %p for pid %d\n", offset, size, address, getpid()); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); mprotect((void *)offset, size, PROT_READ); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); break; case 'w': case 'W': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx mapped at %p for pid %d\n", offset, size, address, getpid()); printf("===== /proc/%d/maps =====\n", getpid()); snprintf(buf, sizeof(buf), "cat /proc/%d/maps", getpid()); system(buf); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); printf("===== READING =====\n"); for (i = 0; i < 0x10; i++) printf("%02x ", (unsigned int)((unsigned char *)address)[i]); printf("\n"); if (c == 'w') { printf("===== WRITING =====\n"); for (i = 0; i < size; i+=2) { ((char *)address)[i] = i & 0xff; ((char *)address)[i+1] = i & 0xff; } } printf("===== READING =====\n"); for (i = 0; i < 0x10; i++) printf("%02x ", (unsigned int)((unsigned char *)address)[i]); printf("\n"); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); break; case 'L': context = strtoul(optarg, &pt, 0); offset = strtoul(pt+1, &pt, 0); size = strtoul(pt+1, &pt, 0); loops = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } lock = address; #if 1 { int counter = 0; struct timeval loop_start, loop_end; struct timeval lock_start, lock_end; double wt; #define HISTOSIZE 9 int histo[HISTOSIZE]; int output = 0; int fast = 0; if (loops < 0) { loops = -loops; ++output; } for (i = 0; i < HISTOSIZE; i++) histo[i] = 0; gettimeofday(&loop_start, NULL); for (i = 0; i < loops; i++) { gettimeofday(&lock_start, NULL); DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast); gettimeofday(&lock_end, NULL); DRM_UNLOCK(fd,lock,context); ++counter; wt = usec(&lock_end, &lock_start); if (wt <= 2.5) ++histo[8]; if (wt < 5.0) ++histo[0]; else if (wt < 50.0) ++histo[1]; else if (wt < 500.0) ++histo[2]; else if (wt < 5000.0) ++histo[3]; else if (wt < 50000.0) ++histo[4]; else if (wt < 500000.0) ++histo[5]; else if (wt < 5000000.0) ++histo[6]; else ++histo[7]; if (output) printf( "%.2f uSec, %d fast\n", wt, fast); } gettimeofday(&loop_end, NULL); printf( "Average wait time = %.2f usec, %d fast\n", usec(&loop_end, &loop_start) / counter, fast); printf( "%9d <= 2.5 uS\n", histo[8]); printf( "%9d < 5 uS\n", histo[0]); printf( "%9d < 50 uS\n", histo[1]); printf( "%9d < 500 uS\n", histo[2]); printf( "%9d < 5000 uS\n", histo[3]); printf( "%9d < 50000 uS\n", histo[4]); printf( "%9d < 500000 uS\n", histo[5]); printf( "%9d < 5000000 uS\n", histo[6]); printf( "%9d >= 5000000 uS\n", histo[7]); } #else printf( "before lock: 0x%08x\n", lock->lock); printf( "lock: 0x%08x\n", lock->lock); sleep(5); printf( "unlock: 0x%08x\n", lock->lock); #endif break; default: fprintf( stderr, "Usage: drmstat [options]\n" ); return 1; } return r; }
/* 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; }
static struct intel_region * intel_recreate_static(struct intel_context *intel, const char *name, struct intel_region *region, intelRegion *region_desc) { intelScreenPrivate *intelScreen = intel->intelScreen; int ret; if (region == NULL) { region = calloc(sizeof(*region), 1); region->refcount = 1; } if (intel->ctx.Visual.rgbBits == 24) region->cpp = 4; else region->cpp = intel->ctx.Visual.rgbBits / 8; region->pitch = intelScreen->pitch; region->width = intelScreen->width; region->height = intelScreen->height; if (region->buffer != NULL) { dri_bo_unreference(region->buffer); region->buffer = NULL; } if (intel->ttm) { assert(region_desc->bo_handle != -1); region->buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, region_desc->bo_handle); ret = dri_bo_get_tiling(region->buffer, ®ion->tiling, ®ion->bit_6_swizzle); if (ret != 0) { fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n", region_desc->bo_handle, name, strerror(-ret)); intel_region_release(®ion); return NULL; } } else { if (region->classic_map != NULL) { drmUnmap(region->classic_map, region->pitch * region->cpp * region->height); region->classic_map = NULL; } ret = drmMap(intel->driFd, region_desc->handle, region->pitch * region->cpp * region->height, ®ion->classic_map); if (ret != 0) { fprintf(stderr, "Failed to drmMap %s buffer\n", name); free(region); return NULL; } region->buffer = intel_bo_fake_alloc_static(intel->bufmgr, name, region_desc->offset, region->pitch * region->cpp * region->height, region->classic_map); /* The sarea just gives us a boolean for whether it's tiled or not, * instead of which tiling mode it is. Guess. */ if (region_desc->tiled) { if (IS_965(intel->intelScreen->deviceID) && region_desc == &intelScreen->depth) region->tiling = I915_TILING_Y; else region->tiling = I915_TILING_X; } else { region->tiling = I915_TILING_NONE; } region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE; } assert(region->buffer != NULL); return region; }
Bool isDRI1Connected(VADriverContextP ctx, char **driver_name) { struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; int direct_capable; int driver_major; int driver_minor; int driver_patch; int newlyopened; char *BusID; drm_magic_t magic; *driver_name = NULL; dri_state->base.fd = -1; dri_state->pSAREA = MAP_FAILED; dri_state->base.auth_type = VA_NONE; if (!VA_DRIQueryDirectRenderingCapable(ctx->native_dpy, ctx->x11_screen, &direct_capable)) goto err_out0; if (!direct_capable) goto err_out0; if (!VA_DRIGetClientDriverName(ctx->native_dpy, ctx->x11_screen, &driver_major, &driver_minor, &driver_patch, driver_name)) goto err_out0; if (!VA_DRIOpenConnection(ctx->native_dpy, ctx->x11_screen, &dri_state->hSAREA, &BusID)) goto err_out0; dri_state->base.fd = drmOpenOnce(NULL, BusID, &newlyopened); XFree(BusID); if (dri_state->base.fd < 0) goto err_out1; if (drmGetMagic(dri_state->base.fd, &magic)) goto err_out1; if (newlyopened && !VA_DRIAuthConnection(ctx->native_dpy, ctx->x11_screen, magic)) goto err_out1; if (drmMap(dri_state->base.fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA)) goto err_out1; if (!VA_DRICreateContext(ctx->native_dpy, ctx->x11_screen, DefaultVisual(ctx->native_dpy, ctx->x11_screen), &dri_state->hwContextID, &dri_state->hwContext)) goto err_out1; dri_state->base.auth_type = VA_DRI1; dri_state->createDrawable = dri1CreateDrawable; dri_state->destroyDrawable = dri1DestroyDrawable; dri_state->swapBuffer = dri1SwapBuffer; dri_state->getRenderingBuffer = dri1GetRenderingBuffer; dri_state->close = dri1Close; return True; err_out1: if (dri_state->pSAREA != MAP_FAILED) drmUnmap(dri_state->pSAREA, SAREA_MAX); if (dri_state->base.fd >= 0) drmCloseOnce(dri_state->base.fd); VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen); err_out0: if (*driver_name) XFree(*driver_name); dri_state->pSAREA = MAP_FAILED; dri_state->base.fd = -1; *driver_name = NULL; return False; }