[Intel-gfx] [PATCH] manage pixmaps with EXA

Jesse Barnes jbarnes at virtuousgeek.org
Thu Apr 9 01:56:17 CEST 2009


I started looking at #20739 and it appears to be a server bug in the
EXA migration code somewhere.  Rather than digging through that when
we're likely to remove EXA support soon, I just added support for
driver managed pixmaps, which fixes also fixes the bug.

This is a fairly significant change so close to release, but I thought
I'd post it for comments.

The patch isn't actually as big as it appears; it mainly moves the UXA
pixmap create/destroy routines up above the EXA init call so they can
be used for both cases.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/src/i830.h b/src/i830.h
index f933917..0f80b93 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -520,8 +520,8 @@ typedef struct _I830Rec {
 #endif
 #ifdef I830_USE_UXA
    uxa_driver_t *uxa_driver;
-   Bool need_flush;
 #endif
+   Bool need_flush;
    Bool need_sync;
 #if defined(I830_USE_EXA) || defined(I830_USE_UXA)
    PixmapPtr pSrcPixmap;
diff --git a/src/i830_accel.c b/src/i830_accel.c
index 9f5bcb5..2ff8bd2 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -67,28 +67,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 unsigned long
 intel_get_pixmap_offset(PixmapPtr pPix)
 {
-#if defined(I830_USE_EXA) || defined(I830_USE_UXA)
     ScreenPtr pScreen = pPix->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    if (pI830->accel == ACCEL_EXA)
-	return exaGetPixmapOffset(pPix);
-#endif
     return (unsigned long)pPix->devPrivate.ptr - (unsigned long)pI830->FbBase;
 }
 
 unsigned long
 intel_get_pixmap_pitch(PixmapPtr pPix)
 {
-#ifdef I830_USE_EXA
-    ScreenPtr pScreen = pPix->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    if (pI830->accel == ACCEL_EXA)
-	return exaGetPixmapPitch(pPix);
-#endif
     return (unsigned long)pPix->devKind;
 }
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 39011bc..449ac5d 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -517,8 +517,6 @@ i830_transform_is_affine (PictTransformPtr t)
     return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
 }
 
-#ifdef XF86DRM_MODE
-
 static void *
 I830EXACreatePixmap(ScreenPtr screen, int size, int align)
 {
@@ -563,63 +561,86 @@ static Bool I830EXAPixmapIsOffscreen(PixmapPtr pPix)
     return FALSE;
 }
 
-static Bool I830EXAPrepareAccess(PixmapPtr pPix, int index)
+static Bool
+i830_prepare_access (PixmapPtr pixmap, uxa_access_t access)
 {
-    ScreenPtr screen = pPix->drawable.pScreen;
-    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-    struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
+    dri_bo *bo = i830_get_pixmap_bo (pixmap);
 
-    if (!driver_priv) {
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no driver private?\n",
-		   __FUNCTION__);
-	return FALSE;
-    }
+    if (bo) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	I830Ptr i830 = I830PTR(scrn);
+	
+	intel_batch_flush(scrn, FALSE);
+	/* XXX: dri_bo_map should handle syncing for us, what's the deal? */
+	if (i830->need_sync) {
+	    I830Sync(scrn);
+	    i830->need_sync = FALSE;
+	}
 
-    if (!driver_priv->bo) {
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no buffer object?\n",
-		   __FUNCTION__);
-	return TRUE;
-    }
+	/* No VT sema or GEM?  No GTT mapping. */
+	if (!scrn->vtSema || !i830->memory_manager) {
+	    if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
+		return FALSE;
+	    pixmap->devPrivate.ptr = bo->virtual;
+	    return TRUE;
+	}
 
-    intel_batch_flush(scrn, FALSE);
-    if (i830->need_sync) {
-	I830Sync(scrn);
-	i830->need_sync = FALSE;
-    }
-    if (drm_intel_gem_bo_map_gtt(driver_priv->bo)) {
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
-		   __FUNCTION__);
-	return FALSE;
+	/* Kernel manages fences at GTT map/fault time */
+	if (i830->kernel_exec_fencing) {
+	    if (drm_intel_gem_bo_map_gtt(bo)) {
+		xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
+			   __FUNCTION__);
+		return FALSE;
+	    }
+	    pixmap->devPrivate.ptr = bo->virtual;
+	} else { /* or not... */
+	    if (drm_intel_bo_pin(bo, 4096) != 0)
+		return FALSE;
+	    drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
+	    pixmap->devPrivate.ptr = i830->FbBase + bo->offset;
+	}
     }
-    pPix->devPrivate.ptr = driver_priv->bo->virtual;
-
     return TRUE;
 }
 
-static void I830EXAFinishAccess(PixmapPtr pPix, int index)
+static Bool
+i830_exa_prepare_access(PixmapPtr pixmap, int index)
 {
-    ScreenPtr screen = pPix->drawable.pScreen;
-    ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-    I830Ptr i830 = I830PTR(scrn);
-    struct i830_exa_pixmap_priv *driver_priv = exaGetPixmapDriverPrivate(pPix);
+    return i830_prepare_access(pixmap, UXA_ACCESS_RW);
+}
 
-    if (!driver_priv) {
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no driver private?\n",
-		   __FUNCTION__);
-	return;
-    }
+static void
+i830_finish_access (PixmapPtr pixmap)
+{
+    dri_bo *bo = i830_get_pixmap_bo (pixmap);
+
+    if (bo) {
+	ScreenPtr screen = pixmap->drawable.pScreen;
+	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+	I830Ptr i830 = I830PTR(scrn);
+
+	if (bo == i830->front_buffer->bo)
+	    i830->need_flush = TRUE;
 
-    if (!driver_priv->bo) {
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no buffer object?\n",
-		   __FUNCTION__);
-	return;
+	if (!scrn->vtSema || !i830->memory_manager) {
+	    dri_bo_unmap(bo);
+	    pixmap->devPrivate.ptr = NULL;
+	    return;
+	}
+
+	if (i830->kernel_exec_fencing)
+	    drm_intel_gem_bo_unmap_gtt(bo);
+	else
+	    drm_intel_bo_unpin(bo);
+	pixmap->devPrivate.ptr = NULL;
     }
+}
 
-    dri_bo_unmap(driver_priv->bo);
-    pPix->devPrivate.ptr = NULL;
-    if (driver_priv->bo == i830->front_buffer->bo)
-	i830->need_flush = TRUE;
+static void
+i830_exa_finish_access (PixmapPtr pixmap, int index)
+{
+    i830_finish_access(pixmap);
 }
 
 static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int width, int height,
@@ -634,15 +655,6 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int width, int height,
     if (!driver_priv)
 	return FALSE;
 
-    if (pI830->use_drm_mode &&
-	drmmode_is_rotate_pixmap(pScrn, pPixData, &driver_priv->bo)) {
-	/* this is a rotate pixmap */
-	dri_bo_unmap(driver_priv->bo);
-	dri_bo_reference(driver_priv->bo);
-        miModifyPixmapHeader(pPix, width, height, depth,
-			     bitsPerPixel, devKind, NULL);
-    }
-
     if (pPixData == pI830->FbBase + pScrn->fbOffset) {
 	if (driver_priv->bo)
 		dri_bo_unreference(driver_priv->bo);
@@ -660,8 +672,6 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int width, int height,
     return FALSE;
 }
 
-#endif /* XF86DRM_MODE */
-
 Bool
 I830EXAInit(ScreenPtr pScreen)
 {
@@ -688,37 +698,19 @@ I830EXAInit(ScreenPtr pScreen)
 	       "EXA compatibility mode.  Output rotation rendering "
 	       "performance may suffer\n");
 #endif
-    if (!pI830->use_drm_mode) {
-	pI830->EXADriverPtr->memoryBase = pI830->FbBase;
-	if (pI830->exa_offscreen) {
-	    pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
-	    pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
-		pI830->exa_offscreen->size;
-	} else {
-	    pI830->EXADriverPtr->offScreenBase = pI830->FbMapSize;
-	    pI830->EXADriverPtr->memorySize = pI830->FbMapSize;
-	}
-	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
-    } else {
-#ifdef XF86DRM_MODE
-	pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
-	pI830->EXADriverPtr->PrepareAccess = I830EXAPrepareAccess;
-	pI830->EXADriverPtr->FinishAccess = I830EXAFinishAccess;
+
+    pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
+    pI830->EXADriverPtr->PrepareAccess = i830_exa_prepare_access;
+    pI830->EXADriverPtr->FinishAccess = i830_exa_finish_access;
+#if EXA_VERSION_MINOR >= 2
+    pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen;
+#endif
 #if EXA_VERSION_MINOR >= 4
-	pI830->EXADriverPtr->CreatePixmap = I830EXACreatePixmap;
-	pI830->EXADriverPtr->DestroyPixmap = I830EXADestroyPixmap;
-	pI830->EXADriverPtr->PixmapIsOffscreen = I830EXAPixmapIsOffscreen;
-	pI830->EXADriverPtr->ModifyPixmapHeader = I830EXAModifyPixmapHeader;
+    pI830->EXADriverPtr->CreatePixmap = I830EXACreatePixmap;
+    pI830->EXADriverPtr->DestroyPixmap = I830EXADestroyPixmap;
+    pI830->EXADriverPtr->PixmapIsOffscreen = I830EXAPixmapIsOffscreen;
+    pI830->EXADriverPtr->ModifyPixmapHeader = I830EXAModifyPixmapHeader;
 #endif
-#endif /* XF86DRM_MODE */
-    }
-
-    DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, "
-	    "memorySize 0x%x\n",
-	    pI830->EXADriverPtr->memoryBase,
-	    pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
-	    pI830->EXADriverPtr->offScreenBase,
-	    pI830->EXADriverPtr->memorySize);
 
     pI830->EXADriverPtr->pixmapOffsetAlign = pI830->accel_pixmap_offset_alignment;
     pI830->EXADriverPtr->pixmapPitchAlign = pI830->accel_pixmap_pitch_alignment;
@@ -757,10 +749,6 @@ I830EXAInit(ScreenPtr pScreen)
  	pI830->EXADriverPtr->Composite = i965_composite;
  	pI830->EXADriverPtr->DoneComposite = i830_done_composite;
     }
-#if EXA_VERSION_MINOR >= 2
-    if (!pI830->use_drm_mode)
-	pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen;
-#endif
 
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -816,7 +804,7 @@ i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo)
 	dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
     }
 #endif
-#ifdef XF86DRM_MODE
+
     if (i830->accel == ACCEL_EXA) {
 	struct i830_exa_pixmap_priv *driver_priv =
 	    exaGetPixmapDriverPrivate(pixmap);
@@ -825,7 +813,7 @@ i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo)
 	    driver_priv->bo = bo;
 	}
     }
-#endif
+
 }
 #if defined(I830_USE_UXA)
 
@@ -835,76 +823,6 @@ i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
     dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
 }
 
-static Bool
-i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
-{
-    dri_bo *bo = i830_get_pixmap_bo (pixmap);
-
-    if (bo) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	I830Ptr i830 = I830PTR(scrn);
-	
-	intel_batch_flush(scrn, FALSE);
-	/* XXX: dri_bo_map should handle syncing for us, what's the deal? */
-	if (i830->need_sync) {
-	    I830Sync(scrn);
-	    i830->need_sync = FALSE;
-	}
-
-	/* No VT sema or GEM?  No GTT mapping. */
-	if (!scrn->vtSema || !i830->memory_manager) {
-	    if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
-		return FALSE;
-	    pixmap->devPrivate.ptr = bo->virtual;
-	    return TRUE;
-	}
-
-	/* Kernel manages fences at GTT map/fault time */
-	if (i830->kernel_exec_fencing) {
-	    if (drm_intel_gem_bo_map_gtt(bo)) {
-		xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
-			   __FUNCTION__);
-		return FALSE;
-	    }
-	    pixmap->devPrivate.ptr = bo->virtual;
-	} else { /* or not... */
-	    if (drm_intel_bo_pin(bo, 4096) != 0)
-		return FALSE;
-	    drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
-	    pixmap->devPrivate.ptr = i830->FbBase + bo->offset;
-	}
-    }
-    return TRUE;
-}
-
-static void
-i830_uxa_finish_access (PixmapPtr pixmap)
-{
-    dri_bo *bo = i830_get_pixmap_bo (pixmap);
-
-    if (bo) {
-	ScreenPtr screen = pixmap->drawable.pScreen;
-	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
-	I830Ptr i830 = I830PTR(scrn);
-
-	if (bo == i830->front_buffer->bo)
-	    i830->need_flush = TRUE;
-
-	if (!scrn->vtSema || !i830->memory_manager) {
-	    dri_bo_unmap(bo);
-	    pixmap->devPrivate.ptr = NULL;
-	    return;
-	}
-
-	if (i830->kernel_exec_fencing)
-	    drm_intel_gem_bo_unmap_gtt(bo);
-	else
-	    drm_intel_bo_unpin(bo);
-	pixmap->devPrivate.ptr = NULL;
-    }
-}
-
 void
 i830_uxa_block_handler (ScreenPtr screen)
 {
@@ -1083,8 +1001,8 @@ i830_uxa_init (ScreenPtr pScreen)
  	i830->uxa_driver->done_composite = i830_done_composite;
     }
 
-    i830->uxa_driver->prepare_access = i830_uxa_prepare_access;
-    i830->uxa_driver->finish_access = i830_uxa_finish_access;
+    i830->uxa_driver->prepare_access = i830_prepare_access;
+    i830->uxa_driver->finish_access = i830_finish_access;
     i830->uxa_driver->pixmap_is_offscreen = i830_uxa_pixmap_is_offscreen;
 
     if(!uxa_driver_init(pScreen, i830->uxa_driver)) {
@@ -1119,9 +1037,11 @@ extern void ExaOffscreenMarkUsed(PixmapPtr);
 unsigned long long
 I830TexOffsetStart(PixmapPtr pPix)
 {
-    exaMoveInPixmap(pPix);
-    ExaOffscreenMarkUsed(pPix);
+    dri_bo *bo = i830_get_pixmap_bo(pPix);
+
+    if (!bo)
+	return 0;
 
-    return exaGetPixmapOffset(pPix);
+    return bo->offset;
 }
 #endif



More information about the Intel-gfx mailing list