📄 radeon_dri.c
字号:
return FALSE; } /* DRIScreenInit doesn't add all the * common mappings. Add additional * mappings here. */ if (!RADEONDRIMapInit(info, pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } /* DRIScreenInit adds the frame buffer map, but we need it as well */ { void *scratch_ptr; int scratch_int; DRIGetDeviceInfo(pScreen, &info->fbHandle, &scratch_int, &scratch_int, &scratch_int, &scratch_int, &scratch_ptr); } /* FIXME: When are these mappings unmapped? */ if (!RADEONInitVisualConfigs(pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n"); return TRUE;}/* Finish initializing the device-dependent DRI state, and call * DRIFinishScreenInit() to complete the device-independent DRI * initialization. */Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONSAREAPrivPtr pSAREAPriv; RADEONDRIPtr pRADEONDRI; info->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; /* info->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit * because *DRIKernelInit requires that the hardware lock is held by * the X server, and the first time the hardware lock is grabbed is * in DRIFinishScreenInit. */ if (!DRIFinishScreenInit(pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } /* Initialize the kernel data structures */ if (!RADEONDRIKernelInit(info, pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } /* Initialize the vertex buffers list */ if (!RADEONDRIBufInit(info, pScreen)) { RADEONDRICloseScreen(pScreen); return FALSE; } /* Initialize IRQ */ RADEONDRIIrqInit(info, pScreen); /* Initialize kernel GART memory manager */ RADEONDRIGartHeapInit(info, pScreen); /* Initialize and start the CP if required */ RADEONDRICPInit(pScrn); /* Initialize the SAREA private data structure */ pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate; pRADEONDRI->deviceID = info->Chipset; pRADEONDRI->width = pScrn->virtualX; pRADEONDRI->height = pScrn->virtualY; pRADEONDRI->depth = pScrn->depth; pRADEONDRI->bpp = pScrn->bitsPerPixel; pRADEONDRI->IsPCI = info->IsPCI; pRADEONDRI->AGPMode = info->agpMode; pRADEONDRI->frontOffset = info->frontOffset; pRADEONDRI->frontPitch = info->frontPitch; pRADEONDRI->backOffset = info->backOffset; pRADEONDRI->backPitch = info->backPitch; pRADEONDRI->depthOffset = info->depthOffset; pRADEONDRI->depthPitch = info->depthPitch; pRADEONDRI->textureOffset = info->textureOffset; pRADEONDRI->textureSize = info->textureSize; pRADEONDRI->log2TexGran = info->log2TexGran; pRADEONDRI->registerHandle = info->registerHandle; pRADEONDRI->registerSize = info->registerSize; pRADEONDRI->statusHandle = info->ringReadPtrHandle; pRADEONDRI->statusSize = info->ringReadMapSize; pRADEONDRI->gartTexHandle = info->gartTexHandle; pRADEONDRI->gartTexMapSize = info->gartTexMapSize; pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran; pRADEONDRI->gartTexOffset = info->gartTexStart; pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);#ifdef PER_CONTEXT_SAREA /* Set per-context SAREA size */ pRADEONDRI->perctx_sarea_size = info->perctx_sarea_size;#endif /* Have shadowfb run only while there is 3d active. */ if (info->allowPageFlip /* && info->drmMinor >= 3 */) { ShadowFBInit( pScreen, RADEONDRIRefreshArea ); } else { info->allowPageFlip = 0; } return TRUE;}/** * This function will attempt to get the Radeon hardware back into shape * after a resume from disc. * * Charl P. Botha <http://cpbotha.net> */void RADEONDRIResume(ScreenPtr pScreen){ int _ret; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); if (info->drmMinor >= 9) { xf86DrvMsg(pScreen->myNum, X_INFO, "[RESUME] Attempting to re-init Radeon hardware.\n"); } else { xf86DrvMsg(pScreen->myNum, X_WARNING, "[RESUME] Cannot re-init Radeon hardware, DRM too old\n" "(need 1.9.0 or newer)\n"); return; } if (!info->IsPCI) { if (!RADEONSetAgpMode(info, pScreen)) return; RADEONSetAgpBase(info); } _ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_RESUME); if (_ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: CP resume %d\n", __FUNCTION__, _ret); /* FIXME: return? */ } RADEONEngineRestore(pScrn); RADEONDRICPInit(pScrn);}/* The screen is being closed, so clean up any state and free any * resources used by the DRI. */void RADEONDRICloseScreen(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); drmRadeonInit drmInfo; RING_LOCALS; /* Stop the CP */ if (info->directRenderingEnabled) { /* If we've generated any CP commands, we must flush them to the * kernel module now. */ if (info->CPInUse) { RADEON_FLUSH_CACHE(); RADEON_WAIT_UNTIL_IDLE(); RADEONCPReleaseIndirect(pScrn); info->CPInUse = FALSE; } RADEONCP_STOP(pScrn, info); } if (info->irq) { drmCtlUninstHandler(info->drmFD); info->irq = 0; info->ModeReg.gen_int_cntl = 0; } /* De-allocate vertex buffers */ if (info->buffers) { drmUnmapBufs(info->buffers); info->buffers = NULL; } /* De-allocate all kernel resources */ memset(&drmInfo, 0, sizeof(drmRadeonInit)); drmInfo.func = DRM_RADEON_CLEANUP_CP; drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT, &drmInfo, sizeof(drmRadeonInit)); /* De-allocate all GART resources */ if (info->gartTex) { drmUnmap(info->gartTex, info->gartTexMapSize); info->gartTex = 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(info->drmFD, info->agpMemHandle); drmAgpFree(info->drmFD, info->agpMemHandle); info->agpMemHandle = DRM_AGP_NO_HANDLE; drmAgpRelease(info->drmFD); } if (info->pciMemHandle) { drmScatterGatherFree(info->drmFD, info->pciMemHandle); info->pciMemHandle = 0; } /* De-allocate all DRI resources */ DRICloseScreen(pScreen); /* De-allocate all DRI data structures */ if (info->pDRIInfo) { if (info->pDRIInfo->devPrivate) { xfree(info->pDRIInfo->devPrivate); info->pDRIInfo->devPrivate = NULL; } DRIDestroyInfoRec(info->pDRIInfo); info->pDRIInfo = NULL; } if (info->pVisualConfigs) { xfree(info->pVisualConfigs); info->pVisualConfigs = NULL; } if (info->pVisualConfigsPriv) { xfree(info->pVisualConfigsPriv); info->pVisualConfigsPriv = NULL; }}/* Fullscreen hooks. The DRI fullscreen mode can probably be removed as * it adds little or nothing above the mechanism below (and isn't widely * used). */static Bool RADEONDRIOpenFullScreen(ScreenPtr pScreen){ return TRUE;}static Bool RADEONDRICloseFullScreen(ScreenPtr pScreen){ return TRUE;}/* Use callbacks from dri.c to support pageflipping mode for a single * 3d context without need for any specific full-screen extension. * * Also use these callbacks to allocate and free 3d-specific memory on * demand. *//* Use the shadowfb module to maintain a list of dirty rectangles. * These are blitted to the back buffer to keep both buffers clean * during page-flipping when the 3d application isn't fullscreen. * * Unlike most use of the shadowfb code, both buffers are in video memory. * * An alternative to this would be to organize for all on-screen drawing * operations to be duplicated for the two buffers. That might be * faster, but seems like a lot more work... */static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox){ RADEONInfoPtr info = RADEONPTR(pScrn); int i; RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); /* Don't want to do this when no 3d is active and pages are * right-way-round */ if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0) return; (*info->accel->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, (CARD32)(-1), -1); for (i = 0 ; i < num ; i++, pbox++) { int xa = max(pbox->x1, 0), xb = min(pbox->x2, pScrn->virtualX-1); int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1); if (xa <= xb && ya <= yb) { (*info->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya, xa + info->backX, ya + info->backY, xb - xa + 1, yb - ya + 1); } }}static void RADEONEnablePageFlip(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); if (info->allowPageFlip) { /* Duplicate the frontbuffer to the backbuffer */ (*info->accel->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, (CARD32)(-1), -1); (*info->accel->SubsequentScreenToScreenCopy)(pScrn, 0, 0, info->backX, info->backY, pScrn->virtualX, pScrn->virtualY); pSAREAPriv->pfAllowPageFlip = 1; }}static void RADEONDisablePageFlip(ScreenPtr pScreen){ /* Tell the clients not to pageflip. How? * -- Field in sarea, plus bumping the window counters. * -- DRM needs to cope with Front-to-Back swapbuffers. */ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); pSAREAPriv->pfAllowPageFlip = 0;}static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen){ RADEONDisablePageFlip(pScreen);}static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen){ /* Let the remaining 3d app start page flipping again */ RADEONEnablePageFlip(pScreen);}static void RADEONDRITransitionTo3d(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); FBAreaPtr fbarea; int width, height; /* reserve offscreen area for back and depth buffers and textures */ /* If we still have an area for the back buffer reserved, free it * first so we always start with all free offscreen memory, except * maybe for Xv */ if (info->backArea) { xf86FreeOffscreenArea(info->backArea); info->backArea = NULL; } xf86PurgeUnlockedOffscreenAreas(pScreen); xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0); /* Free Xv linear offscreen memory if necessary */ if (height < (info->depthTexLines + info->backLines)) { xf86FreeOffscreenLinear(info->videoLinear); info->videoLinear = NULL; xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0); } /* Reserve placeholder area so the other areas will match the * pre-calculated offsets */ fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, height - info->depthTexLines - info->backLines, pScrn->displayWidth, NULL, NULL, NULL); if (!fbarea) xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve placeholder " "offscreen area, you might experience screen corruption\n"); info->backArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, info->backLines, pScrn->displayWidth, NULL, NULL, NULL); if (!info->backArea) xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen " "area for back buffer, you might experience screen " "corruption\n"); info->depthTexArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, info->depthTexLines, pScrn->displayWidth, NULL, NULL, NULL); if (!info->depthTexArea) xf86DrvMsg(pScreen->myNum, X_ERROR, "Unable to reserve offscreen " "area for depth buffer and textures, you might " "experience screen corruption\n"); xf86FreeOffscreenArea(fbarea); RADEONEnablePageFlip(pScreen); info->have3DWindows = 1; if (info->cursor_start) xf86ForceHWCursor (pScreen, TRUE);}static void RADEONDRITransitionTo2d(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); /* Shut down shadowing if we've made it back to the front page */ if (pSAREAPriv->pfCurrentPage == 0) { RADEONDisablePageFlip(pScreen); xf86FreeOffscreenArea(info->backArea); info->backArea = NULL; } else { xf86DrvMsg(pScreen->myNum, X_WARNING, "[dri] RADEONDRITransitionTo2d: " "kernel failed to unflip buffers.\n"); } xf86FreeOffscreenArea(info->depthTexArea); info->have3DWindows = 0; if (info->cursor_start) xf86ForceHWCursor (pScreen, FALSE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -