📄 r128_dri.c
字号:
case PCI_CHIP_RAGE128PF: case PCI_CHIP_RAGE128TF: case PCI_CHIP_RAGE128TL: case PCI_CHIP_RAGE128TR: /* FIXME: ATI documentation does not specify if the following chips are * AGP or PCI, it just mentions their PCI IDs. I'm assuming they're AGP * until I get more correct information. <mharris@redhat.com> */ case PCI_CHIP_RAGE128PA: case PCI_CHIP_RAGE128PB: case PCI_CHIP_RAGE128PC: case PCI_CHIP_RAGE128PE: case PCI_CHIP_RAGE128PG: case PCI_CHIP_RAGE128PH: case PCI_CHIP_RAGE128PI: case PCI_CHIP_RAGE128PJ: case PCI_CHIP_RAGE128PK: case PCI_CHIP_RAGE128PL: case PCI_CHIP_RAGE128PM: case PCI_CHIP_RAGE128PN: case PCI_CHIP_RAGE128PO: case PCI_CHIP_RAGE128PQ: case PCI_CHIP_RAGE128PS: case PCI_CHIP_RAGE128PT: case PCI_CHIP_RAGE128PU: case PCI_CHIP_RAGE128PV: case PCI_CHIP_RAGE128PW: case PCI_CHIP_RAGE128PX: case PCI_CHIP_RAGE128SE: case PCI_CHIP_RAGE128SF: case PCI_CHIP_RAGE128SG: case PCI_CHIP_RAGE128SH: case PCI_CHIP_RAGE128SK: case PCI_CHIP_RAGE128SL: case PCI_CHIP_RAGE128SN: case PCI_CHIP_RAGE128TS: case PCI_CHIP_RAGE128TT: case PCI_CHIP_RAGE128TU: default: /* 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 */ break; } return TRUE;}/* Add a map for the MMIO registers that will be accessed by any DRI-based clients. */static Bool R128DRIMapInit(R128InfoPtr info, ScreenPtr pScreen){ int flags; if (info->CCESecure) flags = DRM_READ_ONLY; else flags = 0; /* Map registers */ info->registerSize = R128_MMIOSIZE; if (drmAddMap(info->drmFD, info->MMIOAddr, info->registerSize, DRM_REGISTERS, flags, &info->registerHandle) < 0) { return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] register handle = 0x%08x\n", info->registerHandle); return TRUE;}/* Initialize the kernel data structures. */static int R128DRIKernelInit(R128InfoPtr info, ScreenPtr pScreen){ drmR128Init drmInfo; memset( &drmInfo, 0, sizeof(drmR128Init) ); drmInfo.func = DRM_R128_INIT_CCE; drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); drmInfo.is_pci = info->IsPCI; drmInfo.cce_mode = info->CCEMode; drmInfo.cce_secure = info->CCESecure; drmInfo.ring_size = info->ringSize*1024*1024; drmInfo.usec_timeout = info->CCEusecTimeout; drmInfo.fb_bpp = info->CurrentLayout.pixel_code; drmInfo.depth_bpp = info->CurrentLayout.pixel_code; drmInfo.front_offset = info->frontOffset; drmInfo.front_pitch = info->frontPitch; drmInfo.back_offset = info->backOffset; drmInfo.back_pitch = info->backPitch; drmInfo.depth_offset = info->depthOffset; drmInfo.depth_pitch = info->depthPitch; drmInfo.span_offset = info->spanOffset; drmInfo.fb_offset = info->fbHandle; drmInfo.mmio_offset = info->registerHandle; drmInfo.ring_offset = info->ringHandle; drmInfo.ring_rptr_offset = info->ringReadPtrHandle; drmInfo.buffers_offset = info->bufHandle; drmInfo.agp_textures_offset = info->agpTexHandle; if (drmCommandWrite(info->drmFD, DRM_R128_INIT, &drmInfo, sizeof(drmR128Init)) < 0) return FALSE; return TRUE;}/* Add a map for the vertex buffers that will be accessed by any DRI-based clients. */static Bool R128DRIBufInit(R128InfoPtr info, ScreenPtr pScreen){ /* Initialize vertex buffers */ if (info->IsPCI) { info->bufNumBufs = drmAddBufs(info->drmFD, info->bufMapSize / R128_BUFFER_SIZE, R128_BUFFER_SIZE, DRM_SG_BUFFER, info->bufStart); } else { info->bufNumBufs = drmAddBufs(info->drmFD, info->bufMapSize / R128_BUFFER_SIZE, R128_BUFFER_SIZE, DRM_AGP_BUFFER, info->bufStart); } if (info->bufNumBufs <= 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Could not create vertex/indirect buffers list\n"); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Added %d %d byte vertex/indirect buffers\n", info->bufNumBufs, R128_BUFFER_SIZE); if (!(info->buffers = drmMapBufs(info->drmFD))) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to map vertex/indirect buffers list\n"); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Mapped %d vertex/indirect buffers\n", info->buffers->count); return TRUE;}static void R128DRIIrqInit(R128InfoPtr info, ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; if (!info->irq) { info->irq = drmGetInterruptFromBusID( info->drmFD, ((pciConfigPtr)info->PciInfo->thisCard)->busnum, ((pciConfigPtr)info->PciInfo->thisCard)->devnum, ((pciConfigPtr)info->PciInfo->thisCard)->funcnum); if((drmCtlInstHandler(info->drmFD, info->irq)) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] failure adding irq handler, " "there is a device already using that irq\n" "[drm] falling back to irq-free operation\n"); info->irq = 0; } else { unsigned char *R128MMIO = info->MMIO; info->gen_int_cntl = INREG( R128_GEN_INT_CNTL ); } } if (info->irq) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] dma control initialized, using IRQ %d\n", info->irq);}/* Initialize the CCE state, and start the CCE (if used by the X server) */static void R128DRICCEInit(ScrnInfoPtr pScrn){ R128InfoPtr info = R128PTR(pScrn); /* Turn on bus mastering */ info->BusCntl &= ~R128_BUS_MASTER_DIS; /* CCEMode is initialized in r128_driver.c */ switch (info->CCEMode) { case R128_PM4_NONPM4: info->CCEFifoSize = 0; break; case R128_PM4_192PIO: info->CCEFifoSize = 192; break; case R128_PM4_192BM: info->CCEFifoSize = 192; break; case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break; case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break; case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; } if (info->directRenderingEnabled) { /* Make sure the CCE is on for the X server */ R128CCE_START(pScrn, info); } else { /* Make sure the CCE is off for the X server */ R128CCE_STOP(pScrn, info); }}/* 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. */Bool R128DRIScreenInit(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; R128InfoPtr info = R128PTR(pScrn); DRIInfoPtr pDRIInfo; R128DRIPtr pR128DRI; int major, minor, patch; drmVersionPtr version; /* Check that the GLX, DRI, and DRM modules have been loaded by testing * for known symbols in each module. */ if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] R128DRIScreenInit failed (libdri.a too old)\n"); return FALSE; } /* Check the DRI version */ DRIQueryVersion(&major, &minor, &patch); if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] R128DRIScreenInit failed because of a version mismatch.\n" "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n" "[dri] Disabling the DRI.\n", major, minor, patch, DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); return FALSE; } switch (info->CurrentLayout.pixel_code) { case 8: /* These modes are not supported (yet). */ case 15: case 24: xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] R128DRIScreenInit failed (depth %d not supported). " "[dri] Disabling DRI.\n", info->CurrentLayout.pixel_code); return FALSE; /* Only 16 and 32 color depths are supports currently. */ case 16: case 32: break; } r128_drm_page_size = getpagesize(); /* Create the DRI data structure, and fill it in before calling the DRIScreenInit(). */ if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; info->pDRIInfo = pDRIInfo; pDRIInfo->drmDriverName = R128_DRIVER_NAME; pDRIInfo->clientDriverName = R128_DRIVER_NAME; if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { pDRIInfo->busIdString = DRICreatePCIBusID(info->PciInfo); } else { pDRIInfo->busIdString = xalloc(64); sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", info->PciInfo->bus, info->PciInfo->device, info->PciInfo->func); } pDRIInfo->ddxDriverMajorVersion = R128_VERSION_MAJOR; pDRIInfo->ddxDriverMinorVersion = R128_VERSION_MINOR; pDRIInfo->ddxDriverPatchVersion = R128_VERSION_PATCH; pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr; pDRIInfo->frameBufferSize = info->FbMapSize; pDRIInfo->frameBufferStride = (pScrn->displayWidth * info->CurrentLayout.pixel_bytes); pDRIInfo->ddxDrawableTableEntry = R128_MAX_DRAWABLES; pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES < R128_MAX_DRAWABLES ? SAREA_MAX_DRAWABLES : R128_MAX_DRAWABLES);#ifdef NOT_DONE /* FIXME: Need to extend DRI protocol to pass this size back to * client for SAREA mapping that includes a device private record */ pDRIInfo->SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ /* + shared memory device private rec */#else /* For now the mapping works by using a fixed size defined * in the SAREA header */ if (sizeof(XF86DRISAREARec)+sizeof(R128SAREAPriv)>SAREA_MAX) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] Data does not fit in SAREA. Disabling DRI.\n"); return FALSE; } pDRIInfo->SAREASize = SAREA_MAX;#endif if (!(pR128DRI = (R128DRIPtr)xcalloc(sizeof(R128DRIRec),1))) { DRIDestroyInfoRec(info->pDRIInfo); info->pDRIInfo = NULL; return FALSE; } pDRIInfo->devPrivate = pR128DRI; pDRIInfo->devPrivateSize = sizeof(R128DRIRec); pDRIInfo->contextSize = sizeof(R128DRIContextRec); pDRIInfo->CreateContext = R128CreateContext; pDRIInfo->DestroyContext = R128DestroyContext; pDRIInfo->SwapContext = R128DRISwapContext; pDRIInfo->InitBuffers = R128DRIInitBuffers; pDRIInfo->MoveBuffers = R128DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; pDRIInfo->TransitionTo2d = R128DRITransitionTo2d; pDRIInfo->TransitionTo3d = R128DRITransitionTo3d; pDRIInfo->TransitionSingleToMulti3D = R128DRITransitionSingleToMulti3d; pDRIInfo->TransitionMultiToSingle3D = R128DRITransitionMultiToSingle3d; pDRIInfo->createDummyCtx = TRUE; pDRIInfo->createDummyCtxPriv = FALSE; if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] DRIScreenInit failed. Disabling DRI.\n"); xfree(pDRIInfo->devPrivate); pDRIInfo->devPrivate = NULL; DRIDestroyInfoRec(pDRIInfo); pDRIInfo = NULL; return FALSE; } /* Check the DRM lib version. drmGetLibVersion was not supported in version 1.0, so check for symbol first to avoid possible crash or hang. */ if (xf86LoaderCheckSymbol("drmGetLibVersion")) { version = drmGetLibVersion(info->drmFD); } else { /* drmlib version 1.0.0 didn't have the drmGetLibVersion entry point. Fake it by allocating a version record via drmGetVersion and changing it to version 1.0.0 */ version = drmGetVersion(info->drmFD); version->version_major = 1; version->version_minor = 0; version->version_patchlevel = 0; } if (version) { if (version->version_major != 1 || version->version_minor < 1) { /* incompatible drm library version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] R128DRIScreenInit failed because of a version mismatch.\n" "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" "[dri] Disabling DRI.\n", version->version_major,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -