[Intel-gfx] [PATCH] EXA pixmap management support (for GTT mapping)

Jesse Barnes jbarnes at virtuousgeek.org
Thu Oct 23 00:07:37 CEST 2008


This is a rough patch I've been testing the GTT mapping support with.  It
basically converts the i830 EXA code to doing its own pixmap management, and
makes the driver assume that the kernel will take care of setting up fence
registers for GTT mapped objects (pinned objects included).

Something in the conversion broke render accel, but I haven't found what yet;
could definitely be kernel related given the list management trouble I've got
in the GTT mapping patch.

Anyway I'm open to suggestions on this patch, how to clean it up, etc.  I
think it's about time to remove XAA support now...

Thanks,
Jesse

diff --git a/src/i830_accel.c b/src/i830_accel.c
index fe76fa0..8e3e500 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -67,28 +67,26 @@ 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 defined(I830_USE_EXA) || defined(I830_USE_UXA)
+    dri_bo *bo;
 
-    if (pI830->accel == ACCEL_EXA)
-	return exaGetPixmapOffset(pPix);
-#endif
+    bo = i830_get_pixmap_bo(pPix);
+
+    if (bo)
+	return bo->offset;
+
+    return pI830->front_buffer->offset;
+#else
     return (unsigned long)pPix->devPrivate.ptr - (unsigned long)pI830-
>FbBase;
+#endif
 }
 
 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;
 }
 
@@ -326,13 +324,13 @@ I830AccelInit(ScreenPtr pScreen)
      * so EXA doesn't need to worry.
      */
     if (IS_I965G(pI830)) {
-	pI830->accel_pixmap_offset_alignment = 4 * 2;
-	pI830->accel_pixmap_pitch_alignment = 16;
+	pI830->accel_pixmap_offset_alignment = GTT_PAGE_SIZE;
+	pI830->accel_pixmap_pitch_alignment = 512;
 	pI830->accel_max_x = 8192;
 	pI830->accel_max_y = 8192;
     } else {
-	pI830->accel_pixmap_offset_alignment = 4;
-	pI830->accel_pixmap_pitch_alignment = 16;
+	pI830->accel_pixmap_offset_alignment = GTT_PAGE_SIZE;
+	pI830->accel_pixmap_pitch_alignment = 512;
 	pI830->accel_max_x = 2048;
 	pI830->accel_max_y = 2048;
     }
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 25bcb47..f023ddd 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1955,7 +1955,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
 #endif
 
 #ifdef I830_USE_EXA
-   case ACCEL_EXA: {
+   case ACCEL_EXA:
+   case ACCEL_UXA:
+   {
       XF86ModReqInfo req;
       int errmaj, errmin;
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index e1cf24e..c1135c9 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "xaarop.h"
 #include "i830.h"
 #include "i810_reg.h"
+#include "drmmode_display.h"
 #include <string.h>
 
 #ifdef I830DEBUG
@@ -110,22 +111,19 @@ i830_pixmap_tiled(PixmapPtr pPixmap)
     ScreenPtr pScreen = pPixmap->drawable.pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
+    struct i830_exa_pixmap_priv *driver_priv = 
exaGetPixmapDriverPrivate(pPix);
     unsigned long offset;
 
     offset = intel_get_pixmap_offset(pPixmap);
     if (offset == pI830->front_buffer->offset &&
 	pI830->front_buffer->tiling != TILE_NONE)
-    {
 	return TRUE;
-    }
 
-    return FALSE;
-}
+    /* All private allocations are X tiled */
+    if (driver_priv && driver_priv->bo)
+	return TRUE;
 
-static unsigned long
-i830_pixmap_pitch(PixmapPtr pixmap)
-{
-    return pixmap->devKind;
+    return FALSE;
 }
 
 static int
@@ -134,23 +132,7 @@ i830_pixmap_pitch_is_aligned(PixmapPtr pixmap)
     ScrnInfoPtr pScrn = xf86Screens[pixmap->drawable.pScreen->myNum];
     I830Ptr pI830 = I830PTR(pScrn);
 
-    return i830_pixmap_pitch(pixmap) % pI830->accel_pixmap_pitch_alignment == 
0;
-}
-
-static Bool
-i830_exa_pixmap_is_offscreen(PixmapPtr pPixmap)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-    I830Ptr pI830 = I830PTR(pScrn);
-
-    if ((void *)pPixmap->devPrivate.ptr >= (void *)pI830->FbBase &&
-	(void *)pPixmap->devPrivate.ptr <
-	(void *)(pI830->FbBase + pI830->FbMapSize))
-    {
-	return TRUE;
-    } else {
-	return FALSE;
-    }
+    return intel_get_pixmap_pitch(pixmap) % pI830-
>accel_pixmap_pitch_alignment == 0;
 }
 
 /**
@@ -188,7 +170,7 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel 
planemask, Pixel fg)
 
     i830_exa_check_pitch_2d(pPixmap);
 
-    pitch = i830_pixmap_pitch(pPixmap);
+    pitch = intel_get_pixmap_pitch(pPixmap);
 
     if (!i830_pixmap_pitch_is_aligned(pPixmap))
 	I830FALLBACK("pixmap pitch not aligned");
@@ -218,7 +200,7 @@ I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, 
int y2)
     unsigned long pitch;
     uint32_t cmd;
 
-    pitch = i830_pixmap_pitch(pPixmap);
+    pitch = intel_get_pixmap_pitch(pPixmap);
 
     {
 	BEGIN_BATCH(6);
@@ -307,8 +289,8 @@ I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, 
int dst_x1,
     dst_x2 = dst_x1 + w;
     dst_y2 = dst_y1 + h;
 
-    dst_pitch = i830_pixmap_pitch(pDstPixmap);
-    src_pitch = i830_pixmap_pitch(pI830->pSrcPixmap);
+    dst_pitch = intel_get_pixmap_pitch(pDstPixmap);
+    src_pitch = intel_get_pixmap_pitch(pI830->pSrcPixmap);
 
     {
 	BEGIN_BATCH(8);
@@ -465,8 +447,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)
 {
@@ -517,6 +497,8 @@ static Bool I830EXAPrepareAccess(PixmapPtr pPix, int 
index)
     ScrnInfoPtr scrn = xf86Screens[screen->myNum];
     I830Ptr i830 = I830PTR(scrn);
     struct i830_exa_pixmap_priv *driver_priv = 
exaGetPixmapDriverPrivate(pPix);
+    uint32_t tiling_mode = I915_TILING_X;
+    int ret;
 
     if (!driver_priv) {
 	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: no driver private?\n",
@@ -535,11 +517,20 @@ static Bool I830EXAPrepareAccess(PixmapPtr pPix, int 
index)
 	I830Sync(scrn);
 	i830->need_sync = FALSE;
     }
-    if (dri_gem_bo_map_gtt(driver_priv->bo)) {
+
+    ret = dri_bo_set_tiling(driver_priv->bo, &tiling_mode,
+			    intel_get_pixmap_pitch(pPix));
+    if (ret)
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+		   "%s: failed to set X tiling for offscreen pixmap\n",
+		   __FUNCTION__);
+
+    if (dri_gem_bo_map_gtt(driver_priv->bo, driver_priv->bo->align)) {
 	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map failed\n",
 		   __FUNCTION__);
 	return FALSE;
     }
+
     pPix->devPrivate.ptr = driver_priv->bo->virtual;
 
     return TRUE;
@@ -564,9 +555,8 @@ static void I830EXAFinishAccess(PixmapPtr pPix, int index)
 	return;
     }
 
-    dri_bo_unmap(driver_priv->bo);
     pPix->devPrivate.ptr = NULL;
-    if (driver_priv->bo == i830->front_buffer->bo)
+    if (i830->front_buffer->offset == driver_priv->bo->offset)
 	i830->need_flush = TRUE;
 }
 
@@ -581,7 +571,7 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int 
width, int height,
 
     if (!driver_priv)
 	return FALSE;
-
+#ifdef XF86DRM_MODE
     if (pI830->use_drm_mode &&
 	drmmode_is_rotate_pixmap(pScrn, pPixData, &driver_priv->bo)) {
 	/* this is a rotate pixmap */
@@ -590,6 +580,7 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int 
width, int height,
         miModifyPixmapHeader(pPix, width, height, depth,
 			     bitsPerPixel, devKind, NULL);
     }
+#endif
 
     if (pPixData == pI830->FbBase + pScrn->fbOffset) {
 	if (driver_priv->bo)
@@ -608,8 +599,6 @@ static Bool I830EXAModifyPixmapHeader(PixmapPtr pPix, int 
width, int height,
     return FALSE;
 }
 
-#endif /* XF86DRM_MODE */
-
 Bool
 I830EXAInit(ScreenPtr pScreen)
 {
@@ -625,49 +614,15 @@ I830EXAInit(ScreenPtr pScreen)
 
     pI830->bufferOffset = 0;
     pI830->EXADriverPtr->exa_major = 2;
-    /* If compiled against EXA 2.2, require 2.2 so we can use the
-     * PixmapIsOffscreen hook.
-     */
-#if EXA_VERSION_MINOR >= 2
-    pI830->EXADriverPtr->exa_minor = 2;
-#else
-    pI830->EXADriverPtr->exa_minor = 1;
-    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	       "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;
-#if EXA_VERSION_MINOR >= 4
-	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->exa_minor = 4;
+
+    pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
+    pI830->EXADriverPtr->PrepareAccess = I830EXAPrepareAccess;
+    pI830->EXADriverPtr->FinishAccess = I830EXAFinishAccess;
+    pI830->EXADriverPtr->CreatePixmap = I830EXACreatePixmap;
+    pI830->EXADriverPtr->DestroyPixmap = I830EXADestroyPixmap;
+    pI830->EXADriverPtr->PixmapIsOffscreen = I830EXAPixmapIsOffscreen;
+    pI830->EXADriverPtr->ModifyPixmapHeader = I830EXAModifyPixmapHeader;
     pI830->EXADriverPtr->pixmapOffsetAlign = pI830-
>accel_pixmap_offset_alignment;
     pI830->EXADriverPtr->pixmapPitchAlign = pI830-
>accel_pixmap_pitch_alignment;
     pI830->EXADriverPtr->maxX = pI830->accel_max_x;
@@ -705,10 +660,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,
@@ -742,13 +693,12 @@ i830_get_pixmap_bo(PixmapPtr pixmap)
 	return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
     }
 #endif
-#ifdef XF86DRM_MODE
+
     if (i830->accel == ACCEL_EXA) {
 	struct i830_exa_pixmap_priv *driver_priv =
 	    exaGetPixmapDriverPrivate(pixmap);
 	return driver_priv ? driver_priv->bo : NULL;
     }
-#endif
 
     return NULL;
 }
@@ -957,9 +907,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
diff --git a/src/i830_memory.c b/src/i830_memory.c
index caae135..2391ef3 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -216,10 +216,9 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
 	mem->bound = TRUE;
     }
 
-    if (mem->tiling != TILE_NONE && !pI830->use_drm_mode) {
+    if (mem->tiling != TILE_NONE && !pI830->memory_manager)
 	mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch,
 					mem->allocated_size, mem->tiling);
-    }
 
     return TRUE;
 }
@@ -787,7 +786,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char 
*name,
     mem->end = -1;
     mem->size = size;
     mem->allocated_size = size;
-    mem->alignment = align;
+    mem->alignment = mem->bo->align = align;
     if (flags & NEED_LIFETIME_FIXED)
 	mem->lifetime_fixed_offset = TRUE;
 
@@ -932,7 +931,7 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char 
*name,
 	else
 	    tiling_mode = I915_TILING_Y;
 
-	ret = dri_bo_set_tiling(mem->bo, &tiling_mode);
+	ret = dri_bo_set_tiling(mem->bo, &tiling_mode, mem->pitch);
 	if (ret != 0 || tiling_mode == I915_TILING_NONE) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "Failed to set tiling on %s: %s\n",
@@ -1488,7 +1487,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
 	return FALSE;
 
 #ifdef I830_USE_EXA
-    if (pI830->accel == ACCEL_EXA && !pI830->use_drm_mode) {
+    if (pI830->accel == ACCEL_EXA && !pI830->memory_manager) {
 	if (pI830->exa_offscreen == NULL) {
 	    /* Default EXA to having 3 screens worth of offscreen memory space
 	     * (for pixmaps).
 


More information about the Intel-gfx mailing list