📄 radeon_dri.c
字号:
xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not add vertex/indirect buffers mapping\n"); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] vertex/indirect buffers handle = 0x%08lx\n", info->bufHandle); if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize, (drmAddressPtr)&info->buf) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map vertex/indirect buffers\n"); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", (unsigned long)info->buf); xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] Vertex/indirect buffers contents 0x%08lx\n", *(unsigned long *)(pointer)info->buf); if (drmAddMap(info->drmFD, info->gartTexStart, info->gartTexMapSize, DRM_SCATTER_GATHER, 0, &info->gartTexHandle) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not add GART texture map mapping\n"); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] GART texture map handle = 0x%08lx\n", info->gartTexHandle); if (drmMap(info->drmFD, info->gartTexHandle, info->gartTexMapSize, (drmAddressPtr)&info->gartTex) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map GART texture map\n"); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[pci] GART Texture map mapped at 0x%08lx\n", (unsigned long)info->gartTex); return TRUE;}/* Add a map for the MMIO registers that will be accessed by any * DRI-based clients. */static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen){ /* Map registers */ info->registerSize = RADEON_MMIOSIZE; if (drmAddMap(info->drmFD, info->MMIOAddr, info->registerSize, DRM_REGISTERS, DRM_READ_ONLY, &info->registerHandle) < 0) { return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] register handle = 0x%08lx\n", info->registerHandle); return TRUE;}/* Initialize the kernel data structures */static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; int cpp = info->CurrentLayout.pixel_bytes; drmRadeonInit drmInfo; memset(&drmInfo, 0, sizeof(drmRadeonInit)); if ((info->ChipFamily == CHIP_FAMILY_R200) || (info->ChipFamily == CHIP_FAMILY_RV250) || (info->ChipFamily == CHIP_FAMILY_RV280) ) drmInfo.func = DRM_RADEON_INIT_R200_CP; else drmInfo.func = DRM_RADEON_INIT_CP; drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); drmInfo.is_pci = info->IsPCI; drmInfo.cp_mode = info->CPMode; drmInfo.gart_size = info->gartSize*1024*1024; drmInfo.ring_size = info->ringSize*1024*1024; drmInfo.usec_timeout = info->CPusecTimeout; drmInfo.fb_bpp = info->CurrentLayout.pixel_code; drmInfo.depth_bpp = info->CurrentLayout.pixel_code; drmInfo.front_offset = info->frontOffset; drmInfo.front_pitch = info->frontPitch * cpp; drmInfo.back_offset = info->backOffset; drmInfo.back_pitch = info->backPitch * cpp; drmInfo.depth_offset = info->depthOffset; drmInfo.depth_pitch = info->depthPitch * cpp; 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.gart_textures_offset= info->gartTexHandle; if (drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT, &drmInfo, sizeof(drmRadeonInit)) < 0) return FALSE; /* DRM_RADEON_CP_INIT does an engine reset, which resets some engine * registers back to their default values, so we need to restore * those engine register here. */ RADEONEngineRestore(pScrn); return TRUE;}static void RADEONDRIGartHeapInit(RADEONInfoPtr info, ScreenPtr pScreen){ drmRadeonMemInitHeap drmHeap; /* Start up the simple memory manager for GART space */ if (info->drmMinor >= 6) { drmHeap.region = RADEON_MEM_REGION_GART; drmHeap.start = 0; drmHeap.size = info->gartTexMapSize; if (drmCommandWrite(info->drmFD, DRM_RADEON_INIT_HEAP, &drmHeap, sizeof(drmHeap))) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to initialize GART heap manager\n"); } else { xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Initialized kernel GART heap manager, %d\n", info->gartTexMapSize); } } else { xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Kernel module too old (1.%d) for GART heap manager\n", info->drmMinor); }}/* Add a map for the vertex buffers that will be accessed by any * DRI-based clients. */static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen){ /* Initialize vertex buffers */ info->bufNumBufs = drmAddBufs(info->drmFD, info->bufMapSize / RADEON_BUFFER_SIZE, RADEON_BUFFER_SIZE, info->IsPCI ? DRM_SG_BUFFER : 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, RADEON_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 RADEONDRIIrqInit(RADEONInfoPtr 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 *RADEONMMIO = info->MMIO; info->ModeReg.gen_int_cntl = INREG( RADEON_GEN_INT_CNTL ); } } if (info->irq) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] dma control initialized, using IRQ %d\n", info->irq);}/* Initialize the CP state, and start the CP (if used by the X server) */static void RADEONDRICPInit(ScrnInfoPtr pScrn){ RADEONInfoPtr info = RADEONPTR(pScrn); /* Turn on bus mastering */ info->BusCntl &= ~RADEON_BUS_MASTER_DIS; /* Make sure the CP is on for the X server */ RADEONCP_START(pScrn, info); RADEONSelectBuffer(pScrn, RADEON_FRONT);}/* Initialize the screen-specific data structures for the DRI and the * Radeon. 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 RADEONDRIScreenInit(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); DRIInfoPtr pDRIInfo; RADEONDRIPtr pRADEONDRI; 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("DRIScreenInit")) return FALSE; if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] RADEONDRIScreenInit failed (libdri.a too old)\n"); return FALSE; } /* Check the DRI version */ DRIQueryVersion(&major, &minor, &patch); if (major != 4 || minor < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] RADEONDRIScreenInit failed because of a version " "mismatch.\n" "[dri] libDRI version is %d.%d.%d but version 4.0.x is " "needed.\n" "[dri] Disabling DRI.\n", major, minor, patch); return FALSE; } switch (info->CurrentLayout.pixel_code) { case 8: case 15: case 24: /* These modes are not supported (yet). */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] RADEONInitVisualConfigs failed " "(depth %d not supported). " "Disabling DRI.\n", info->CurrentLayout.pixel_code); return FALSE; /* Only 16 and 32 color depths are supports currently. */ case 16: case 32: break; } /* Create the DRI data structure, and fill it in before calling the * DRIScreenInit(). */ if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; info->pDRIInfo = pDRIInfo; pDRIInfo->drmDriverName = RADEON_DRIVER_NAME; if ( (info->ChipFamily == CHIP_FAMILY_R200) || (info->ChipFamily == CHIP_FAMILY_RV250) || (info->ChipFamily == CHIP_FAMILY_RV280) ) pDRIInfo->clientDriverName = R200_DRIVER_NAME; else pDRIInfo->clientDriverName = RADEON_DRIVER_NAME; pDRIInfo->busIdString = xalloc(64); sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", info->PciInfo->bus, info->PciInfo->device, info->PciInfo->func); pDRIInfo->ddxDriverMajorVersion = RADEON_VERSION_MAJOR; pDRIInfo->ddxDriverMinorVersion = RADEON_VERSION_MINOR; pDRIInfo->ddxDriverPatchVersion = RADEON_VERSION_PATCH; pDRIInfo->frameBufferPhysicalAddress = info->LinearAddr; pDRIInfo->frameBufferSize = info->FbMapSize; pDRIInfo->frameBufferStride = (pScrn->displayWidth * info->CurrentLayout.pixel_bytes); pDRIInfo->ddxDrawableTableEntry = RADEON_MAX_DRAWABLES; pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES < RADEON_MAX_DRAWABLES ? SAREA_MAX_DRAWABLES : RADEON_MAX_DRAWABLES);#ifdef PER_CONTEXT_SAREA /* This is only here for testing per-context SAREAs. When used, the magic number below would be properly defined in a header file. */ info->perctx_sarea_size = 64 * 1024;#endif#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(RADEONSAREAPriv) > SAREA_MAX) { ErrorF("Data does not fit in SAREA\n"); return FALSE; } pDRIInfo->SAREASize = SAREA_MAX;#endif if (!(pRADEONDRI = (RADEONDRIPtr)xcalloc(sizeof(RADEONDRIRec),1))) { DRIDestroyInfoRec(info->pDRIInfo); info->pDRIInfo = NULL; return FALSE; } pDRIInfo->devPrivate = pRADEONDRI; pDRIInfo->devPrivateSize = sizeof(RADEONDRIRec); pDRIInfo->contextSize = sizeof(RADEONDRIContextRec); pDRIInfo->CreateContext = RADEONCreateContext; pDRIInfo->DestroyContext = RADEONDestroyContext; pDRIInfo->SwapContext = RADEONDRISwapContext; pDRIInfo->InitBuffers = RADEONDRIInitBuffers; pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; pDRIInfo->OpenFullScreen = RADEONDRIOpenFullScreen; pDRIInfo->CloseFullScreen = RADEONDRICloseFullScreen; pDRIInfo->TransitionTo2d = RADEONDRITransitionTo2d; pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d; pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d; pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d; 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] RADEONDRIScreenInit 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, version->version_minor, version->version_patchlevel); drmFreeVersion(version); RADEONDRICloseScreen(pScreen); return FALSE; } drmFreeVersion(version); } /* Check the radeon DRM version */ version = drmGetVersion(info->drmFD); if (version) { int req_minor, req_patch; if ((info->ChipFamily == CHIP_FAMILY_R200) || (info->ChipFamily == CHIP_FAMILY_RV250) || (info->ChipFamily == CHIP_FAMILY_RV280)) { req_minor = 5; req_patch = 0; } else {#if X_BYTE_ORDER == X_LITTLE_ENDIAN req_minor = 1; req_patch = 0;#else req_minor = 2; req_patch = 1; #endif } if (version->version_major != 1 || version->version_minor < req_minor || (version->version_minor == req_minor && version->version_patchlevel < req_patch)) { /* Incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] RADEONDRIScreenInit failed because of a version " "mismatch.\n" "[dri] radeon.o kernel module version is %d.%d.%d " "but version 1.%d.%d or newer is needed.\n" "[dri] Disabling DRI.\n", version->version_major, version->version_minor, version->version_patchlevel, req_minor, req_patch); drmFreeVersion(version); RADEONDRICloseScreen(pScreen); return FALSE; } if (version->version_minor < 3) { xf86DrvMsg(pScreen->myNum, X_WARNING, "[dri] Some DRI features disabled because of version " "mismatch.\n" "[dri] radeon.o kernel module version is %d.%d.%d but " "1.3.1 or later is preferred.\n", version->version_major, version->version_minor, version->version_patchlevel); } info->drmMinor = version->version_minor; drmFreeVersion(version); } /* Initialize AGP */ if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) {#if defined(__alpha__) || defined(__powerpc__) info->IsPCI = TRUE; xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP failed to initialize " "-- falling back to PCI mode.\n"); xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] If this is an AGP card, you may want to make sure " "the agpgart\nkernel module is loaded before the radeon " "kernel module.\n");#else RADEONDRICloseScreen(pScreen); return FALSE;#endif } /* Initialize PCI */ if (info->IsPCI && !RADEONDRIPciInit(info, pScreen)) { RADEONDRICloseScreen(pScreen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -