diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c')
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c | 76 |
1 files changed, 67 insertions, 9 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c index 769d45e2e..235acafdd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -491,6 +491,8 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) int nbox; unsigned int color, depth, stencil; unsigned int color_mask, depth_mask, flags; + drmRadeonClearType clear; + drmRadeonClearRect depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; /* FIXME: This should be based on the __GLXvisualConfig info */ color = 0; @@ -521,25 +523,36 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + clear.flags = flags; + clear.clear_color = color; + clear.clear_depth = depth; + clear.color_mask = color_mask; + clear.depth_mask = depth_mask; + clear.depth_boxes = depth_boxes; + pbox = REGION_RECTS(prgn); nbox = REGION_NUM_RECTS(prgn); for (; nbox; nbox--, pbox++) { int ret; - /* drmRadeonClear uses the clip rects to draw instead of the + /* DRM_RADEON_CLEAR uses the clip rects to draw instead of the rect passed to it; however, it uses the rect for the depth clears */ pSAREAPriv->boxes[0].x1 = pbox->x1; - pSAREAPriv->boxes[0].x2 = pbox->x2; pSAREAPriv->boxes[0].y1 = pbox->y1; + pSAREAPriv->boxes[0].x2 = pbox->x2; pSAREAPriv->boxes[0].y2 = pbox->y2; pSAREAPriv->nbox = 1; - ret = drmRadeonClear(info->drmFD, - flags, - color, depth, color_mask, depth_mask, - pSAREAPriv->boxes, pSAREAPriv->nbox); + depth_boxes[0].f[RADEON_CLEAR_X1] = (float)pbox->x1; + depth_boxes[0].f[RADEON_CLEAR_Y1] = (float)pbox->y1; + depth_boxes[0].f[RADEON_CLEAR_X2] = (float)pbox->x2; + depth_boxes[0].f[RADEON_CLEAR_Y2] = (float)pbox->y2; + depth_boxes[0].f[RADEON_CLEAR_DEPTH] = (float)depth; + + ret = drmCommandWrite(info->drmFD, DRM_RADEON_CLEAR, + &clear, sizeof(drmRadeonClearType)); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] DRIInitBuffers timed out, resetting engine...\n"); @@ -1007,6 +1020,9 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) int cpp = info->CurrentLayout.pixel_bytes; drmRadeonInit drmInfo; + memset(&drmInfo, 0, sizeof(drmRadeonInit)); + + drmInfo.func = DRM_RADEON_INIT_CP; drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); drmInfo.is_pci = info->IsPCI; drmInfo.cp_mode = info->CPMode; @@ -1031,9 +1047,11 @@ static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) drmInfo.buffers_offset = info->bufHandle; drmInfo.agp_textures_offset = info->agpTexHandle; - if (drmRadeonInitCP(info->drmFD, &drmInfo) < 0) return FALSE; + if (drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT, + &drmInfo, sizeof(drmRadeonInit)) < 0) + return FALSE; - /* drmRadeonInitCP does an engine reset, which resets some engine + /* 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); @@ -1412,6 +1430,42 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen) 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) { @@ -1572,6 +1626,7 @@ void RADEONDRICloseScreen(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); + drmRadeonInit drmInfo; /* Stop the CP */ if (info->directRenderingEnabled) { @@ -1585,7 +1640,10 @@ void RADEONDRICloseScreen(ScreenPtr pScreen) } /* De-allocate all kernel resources */ - drmRadeonCleanupCP(info->drmFD); + memset(&drmInfo, 0, sizeof(drmRadeonInit)); + drmInfo.func = DRM_RADEON_CLEANUP_CP; + drmCommandWrite(info->drmFD, DRM_RADEON_CP_INIT, + &drmInfo, sizeof(drmRadeonInit)); /* De-allocate all AGP resources */ if (info->agpTex) { |