summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
diff options
context:
space:
mode:
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.c76
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) {