diff options
Diffstat (limited to 'hw/xfree86/dri/dri.c')
-rw-r--r-- | hw/xfree86/dri/dri.c | 144 |
1 files changed, 111 insertions, 33 deletions
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index acef4c54b..4748f17df 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -34,8 +34,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#ifdef XFree86LOADER #include "xf86.h" +#ifdef XFree86LOADER #include "xf86_ansic.h" #else #include <sys/time.h> @@ -57,6 +57,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define _XF86DRI_SERVER_ #include "xf86dristr.h" #include "swaprep.h" +#include "xf86str.h" #include "dri.h" #include "sarea.h" #include "dristruct.h" @@ -113,11 +114,14 @@ Bool DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) { DRIScreenPrivPtr pDRIPriv; - drmContextPtr reserved; + drm_context_t * reserved; int reserved_count; int i, fd, drmWasAvailable; Bool xineramaInCore = FALSE; int err = 0; + char *openbusid; + drmVersionPtr drmlibv; + int drmlibmajor, drmlibminor, drmdimajor, drmdiminor; if (DRIGeneration != serverGeneration) { if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0) @@ -148,8 +152,31 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) drmWasAvailable = drmAvailable(); + /* Check the DRM lib version. + * drmGetLibVersion was not supported in version 1.0, so check for + * symbol first to avoid possible crash or hang. + */ + drmlibmajor = 1; + drmlibminor = 0; + if (xf86LoaderCheckSymbol("drmGetLibVersion")) { + drmlibv = drmGetLibVersion(-1); + if (drmlibv != NULL) { + drmlibmajor = drmlibv->version_major; + drmlibminor = drmlibv->version_minor; + drmFreeVersion(drmlibv); + } + } + + /* Check if the libdrm can handle falling back to loading based on name + * if a busid string is passed. + */ + if (drmlibmajor == 1 && drmlibminor >= 2) + openbusid = pDRIInfo->busIdString; + else + openbusid = NULL; + /* Note that drmOpen will try to load the kernel module, if needed. */ - fd = drmOpen(pDRIInfo->drmDriverName, NULL ); + fd = drmOpen(pDRIInfo->drmDriverName, openbusid); if (fd < 0) { /* failed to open DRM */ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL; @@ -184,7 +211,40 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) pDRIPriv->grabbedDRILock = FALSE; pDRIPriv->drmSIGIOHandlerInstalled = FALSE; - if ((err = drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString)) < 0) { + if (drmlibmajor == 1 && drmlibminor >= 2) { + drmSetVersion sv; + + /* Get the interface version, asking for 1.1. */ + sv.drm_di_major = 1; + sv.drm_di_minor = 1; + sv.drm_dd_major = -1; + err = drmSetInterfaceVersion(pDRIPriv->drmFD, &sv); + if (err == 0) { + drmdimajor = sv.drm_di_major; + drmdiminor = sv.drm_di_minor; + } else { + /* failure, so set it to 1.0.0. */ + drmdimajor = 1; + drmdiminor = 0; + } + } + else { + /* We can't check the DI DRM interface version, so set it to 1.0.0. */ + drmdimajor = 1; + drmdiminor = 0; + } + DRIDrvMsg(pScreen->myNum, X_INFO, + "[drm] DRM interface version %d.%d\n", drmdimajor, drmdiminor); + + /* If the interface minor number is 1.1, then we've opened a DRM device + * that already had the busid set through drmOpen. + */ + if (drmdimajor == 1 && drmdiminor >= 1) + err = 0; + else + err = drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString); + + if (err < 0) { pDRIPriv->directRenderingSupport = FALSE; pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL; drmClose(pDRIPriv->drmFD); @@ -235,7 +295,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) pDRIPriv->hSAREA, pDRIPriv->pSAREA); if (drmAddMap( pDRIPriv->drmFD, - (drmHandle)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress, + (drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress, pDRIPriv->pDriverInfo->frameBufferSize, DRM_FRAME_BUFFER, 0, @@ -424,7 +484,7 @@ DRICloseScreen(ScreenPtr pScreen) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIInfoPtr pDRIInfo; - drmContextPtr reserved; + drm_context_t * reserved; int reserved_count; if (pDRIPriv && pDRIPriv->directRenderingSupport) { @@ -575,7 +635,7 @@ DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable) } Bool -DRIOpenConnection(ScreenPtr pScreen, drmHandlePtr hSAREA, char **busIdString) +DRIOpenConnection(ScreenPtr pScreen, drm_handle_t * hSAREA, char **busIdString) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); @@ -586,7 +646,7 @@ DRIOpenConnection(ScreenPtr pScreen, drmHandlePtr hSAREA, char **busIdString) } Bool -DRIAuthConnection(ScreenPtr pScreen, drmMagic magic) +DRIAuthConnection(ScreenPtr pScreen, drm_magic_t magic) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); @@ -620,18 +680,18 @@ DRIGetClientDriverName(ScreenPtr pScreen, /* DRICreateContextPriv and DRICreateContextPrivFromHandle are helper functions that layer on drmCreateContext and drmAddContextTag. - DRICreateContextPriv always creates a kernel drmContext and then calls + DRICreateContextPriv always creates a kernel drm_context_t and then calls DRICreateContextPrivFromHandle to create a DRIContextPriv structure for - DRI tracking. For the SIGIO handler, the drmContext is associated with + DRI tracking. For the SIGIO handler, the drm_context_t is associated with DRIContextPrivPtr. Any special flags are stored in the DRIContextPriv area and are passed to the kernel (if necessary). DRICreateContextPriv returns a pointer to newly allocated - DRIContextPriv, and returns the kernel drmContext in pHWContext. */ + DRIContextPriv, and returns the kernel drm_context_t in pHWContext. */ DRIContextPrivPtr DRICreateContextPriv(ScreenPtr pScreen, - drmContextPtr pHWContext, + drm_context_t * pHWContext, DRIContextFlags flags) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); @@ -645,7 +705,7 @@ DRICreateContextPriv(ScreenPtr pScreen, DRIContextPrivPtr DRICreateContextPrivFromHandle(ScreenPtr pScreen, - drmContext hHWContext, + drm_context_t hHWContext, DRIContextFlags flags) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); @@ -720,8 +780,8 @@ static Bool DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - __GLXscreenInfo *pGLXScreen = &__glXActiveScreens[pScreen->myNum]; - __GLXvisualConfig *pGLXVis = pGLXScreen->pGlxVisual; + __GLXscreenInfo *pGLXScreen = __glXgetActiveScreen(pScreen->myNum); + __GLcontextModes *modes = pGLXScreen->modes; void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; @@ -734,7 +794,7 @@ DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) for (visNum = 0; visNum < pScreen->numVisuals; visNum++, visual++) { - if (pGLXVis->vid == visual->vid) + if (modes->visualID == visual->vid) break; } if (visNum == pScreen->numVisuals) return FALSE; @@ -781,15 +841,14 @@ DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv) Bool DRICreateContext(ScreenPtr pScreen, VisualPtr visual, - XID context, drmContextPtr pHWContext) + XID context, drm_context_t * pHWContext) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - __GLXscreenInfo *pGLXScreen = &__glXActiveScreens[pScreen->myNum]; - __GLXvisualConfig *pGLXVis = pGLXScreen->pGlxVisual; + __GLXscreenInfo *pGLXScreen = __glXgetActiveScreen(pScreen->myNum); + __GLcontextModes *modes = pGLXScreen->modes; void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; - int visNum; if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) { if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) { @@ -800,12 +859,13 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, } /* Find the GLX visual associated with the one requested */ - for (visNum = 0; - visNum < pGLXScreen->numVisuals; - visNum++, pGLXVis++, pVisualConfigPriv++) - if (pGLXVis->vid == visual->vid) + for (modes = pGLXScreen->modes; modes != NULL; modes = modes->next) { + if (modes->visualID == visual->vid) break; - if (visNum == pGLXScreen->numVisuals) { + pVisualConfigPriv++; + } + + if (modes == NULL) { /* No matching GLX visual found */ return FALSE; } @@ -928,7 +988,7 @@ DRITransitionTo2d(ScreenPtr pScreen) Bool DRICreateDrawable(ScreenPtr pScreen, Drawable id, - DrawablePtr pDrawable, drmDrawablePtr hHWDrawable) + DrawablePtr pDrawable, drm_drawable_t * hHWDrawable) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIDrawablePrivPtr pDRIDrawablePriv; @@ -945,7 +1005,7 @@ DRICreateDrawable(ScreenPtr pScreen, Drawable id, return FALSE; } - /* Only create a drmDrawable once */ + /* Only create a drm_drawable_t once */ if (drmCreateDrawable(pDRIPriv->drmFD, hHWDrawable)) { xfree(pDRIDrawablePriv); return FALSE; @@ -1065,11 +1125,11 @@ DRIGetDrawableInfo(ScreenPtr pScreen, int* W, int* H, int* numClipRects, - XF86DRIClipRectPtr* pClipRects, + drm_clip_rect_t ** pClipRects, int* backX, int* backY, int* numBackClipRects, - XF86DRIClipRectPtr* pBackClipRects) + drm_clip_rect_t ** pBackClipRects) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv; @@ -1165,7 +1225,7 @@ DRIGetDrawableInfo(ScreenPtr pScreen, *W = (int)(pWin->drawable.width); *H = (int)(pWin->drawable.height); *numClipRects = REGION_NUM_RECTS(&pWin->clipList); - *pClipRects = (XF86DRIClipRectPtr)REGION_RECTS(&pWin->clipList); + *pClipRects = (drm_clip_rect_t *)REGION_RECTS(&pWin->clipList); if (!*numClipRects && pDRIPriv->fullscreen) { /* use fake full-screen clip rect */ @@ -1222,7 +1282,7 @@ DRIGetDrawableInfo(ScreenPtr pScreen, Bool DRIGetDeviceInfo(ScreenPtr pScreen, - drmHandlePtr hFrameBuffer, + drm_handle_t * hFrameBuffer, int* fbOrigin, int* fbSize, int* fbStride, @@ -1870,7 +1930,7 @@ DRIGetSAREAPrivate(ScreenPtr pScreen) return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec)); } -drmContext +drm_context_t DRIGetContext(ScreenPtr pScreen) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); @@ -1967,7 +2027,7 @@ DRIOpenFullScreen(ScreenPtr pScreen, DrawablePtr pDrawable) DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; WindowPtr pWin = (WindowPtr)pDrawable; - XF86DRIClipRectPtr pClipRects = (void *)REGION_RECTS(&pWin->clipList); + drm_clip_rect_t * pClipRects = (void *)REGION_RECTS(&pWin->clipList); _DRIAdjustFrame(pScrn, pDRIPriv, pScrn->frameX0, pScrn->frameY0); @@ -2115,3 +2175,21 @@ DRIMoveBuffersHelper( } else *xdir = 1; } + +char * +DRICreatePCIBusID(pciVideoPtr PciInfo) +{ + char *busID; + int domain; + PCITAG tag; + + busID = xalloc(20); + if (busID == NULL) + return NULL; + + tag = pciTag(PciInfo->bus, PciInfo->device, PciInfo->func); + domain = xf86GetPciDomain(tag); + snprintf(busID, 20, "pci:%04x:%02x:%02x.%d", domain, PciInfo->bus, + PciInfo->device, PciInfo->func); + return busID; +} |