[Intel-gfx] [PATCH] uxa: create pixmap private struct for bo pin tracking

Zhenyu Wang zhenyu.z.wang at intel.com
Mon Jan 5 07:27:19 CET 2009


---
 src/i830_exa.c |   44 +++++++++++++++++++++++++++++++++++---------
 1 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/src/i830_exa.c b/src/i830_exa.c
index aeffedd..565da2d 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -733,6 +733,16 @@ I830EXAInit(ScreenPtr pScreen)
 
 #ifdef I830_USE_UXA
 static int uxa_pixmap_index;
+struct _uxa_pixmap_private_t {
+    dri_bo *bo;
+    int pinned;
+};
+
+static struct _uxa_pixmap_private_t *
+i830_get_pixmap_priv(PixmapPtr pixmap)
+{
+    return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
+}
 #endif
 
 dri_bo *
@@ -744,7 +754,9 @@ i830_get_pixmap_bo(PixmapPtr pixmap)
 
 #ifdef I830_USE_UXA
     if (i830->accel == ACCEL_UXA) {
-	return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
+	struct _uxa_pixmap_private_t *priv =
+	    dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
+	return priv ? priv->bo : NULL;
     }
 #endif
 #ifdef XF86DRM_MODE
@@ -763,7 +775,12 @@ i830_get_pixmap_bo(PixmapPtr pixmap)
 static void
 i830_uxa_set_pixmap_bo (PixmapPtr pixmap, dri_bo *bo)
 {
-    dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, bo);
+    struct _uxa_pixmap_private_t *priv;
+
+    priv = (struct _uxa_pixmap_private_t *) xcalloc(1, sizeof(*priv));
+    priv->bo = bo;
+    priv->pinned = 0;
+    dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, priv);
 }
 
 static Bool
@@ -772,6 +789,7 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
     ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
     dri_bo *bo = i830_get_pixmap_bo (pixmap);
+    struct _uxa_pixmap_private_t *priv = i830_get_pixmap_priv (pixmap);
 
     if (bo) {
 	ScreenPtr screen = pixmap->drawable.pScreen;
@@ -786,11 +804,18 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access)
 	}
 
 	if (drm_intel_bo_pin(bo, 4096) != 0) {
-	    /* happen in vt switched */
-	    if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
-		return FALSE;
-	    pixmap->devPrivate.ptr = bo->virtual;
+	    priv->pinned = 0;
+	     /* For tiled front buffer, short-circuit to the GTT mapping. */
+	    if (i830_pixmap_tiled(pixmap)) {
+		drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
+		pixmap->devPrivate.ptr = pI830->FbBase + bo->offset;
+	    } else {
+		if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
+		    return FALSE;
+		pixmap->devPrivate.ptr = bo->virtual;
+	    }
 	} else {
+	    priv->pinned = 1;
 	    drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW);
 	    pixmap->devPrivate.ptr = pI830->FbBase + bo->offset;
 	}
@@ -802,16 +827,17 @@ static void
 i830_uxa_finish_access (PixmapPtr pixmap)
 {
     dri_bo *bo = i830_get_pixmap_bo (pixmap);
+    struct _uxa_pixmap_private_t *priv = i830_get_pixmap_priv (pixmap);
 
     if (bo) {
 	ScreenPtr screen = pixmap->drawable.pScreen;
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
 	I830Ptr i830 = I830PTR(scrn);
 
-	if (bo->virtual)
-	    dri_bo_unmap(bo);
-	else
+	if (priv->pinned)
 	    drm_intel_bo_unpin(bo);
+	else if (!i830_pixmap_tiled(pixmap))
+	    dri_bo_unmap(bo);
 
 	pixmap->devPrivate.ptr = NULL;
 	if (bo == i830->front_buffer->bo)
-- 
1.5.3.8




More information about the Intel-gfx mailing list