xf86-video-intel: 2 commits - src/common.h src/i830_dri.c src/i830_driver.c src/i830_exa.c src/i830.h src/i830_memory.c

Eric Anholt anholt at kemper.freedesktop.org
Tue Jan 27 17:25:59 PST 2009


 src/common.h      |    2 +
 src/i830.h        |    4 +++
 src/i830_dri.c    |   25 +++++++++++--------
 src/i830_driver.c |    1 
 src/i830_exa.c    |   20 ++++++++++++---
 src/i830_memory.c |   71 ++++++++++++++++++++++++++++++++++++++++++------------
 6 files changed, 95 insertions(+), 28 deletions(-)

New commits:
commit 66bc44e8f9a0505c0b11b8042243ca74079da85f
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 27 15:43:58 2009 -0800

    dri2: Use modesetting's master fd instead of opening our own non-master.
    
    This fixes failure to auth DRI2 clients under KMS.

diff --git a/src/i830_dri.c b/src/i830_dri.c
index 7a95d02..f03be43 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1691,7 +1691,17 @@ Bool I830DRI2ScreenInit(ScreenPtr pScreen)
 	    pI830->PciInfo->dev,
 	    pI830->PciInfo->func);
 
-    info.fd = drmOpen("i915", buf);
+    info.fd = -1;
+
+#ifdef XF86DRM_MODE
+    /* Use the already opened (master) fd from modesetting */
+    if (pI830->use_drm_mode)
+	info.fd = pI830->drmSubFD;
+#endif
+
+    if (info.fd < 0)
+	info.fd = drmOpen("i915", buf);
+
     if (info.fd < 0) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to open DRM device\n");
 	return FALSE;
commit 8d4bc36fae50b09a73ba2cfab920adb32141a358
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Mon Jan 26 17:14:06 2009 -0800

    Support tiled back/depth on 915-class hardware with DRI2.
    
    Set alignments, tile settings and flags correctly in the 2D driver to support
    tiled rendering.  UXA's create pixmap function currently assumes the worst
    about the alignment constraints; that should probably be fixed.  Some of the
    1M alignment fixes could probably be done more cleanly as well.

diff --git a/src/common.h b/src/common.h
index 4a87acb..be222df 100644
--- a/src/common.h
+++ b/src/common.h
@@ -367,6 +367,8 @@ extern int I810_DEBUG;
 #define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_G4X(pI810))
 /* dsparb controlled by hw only */
 #define DSPARB_HWCONTROL(pI810) (IS_G4X(pI810))
+/* supports Y tiled surfaces (pre-965 Mesa isn't ready yet) */
+#define SUPPORTS_YTILING(pI810) (IS_I965G(pI830))
 
 #define GTT_PAGE_SIZE			KB(4)
 #define ROUND_TO(x, y)			(((x) + (y) - 1) / (y) * (y))
diff --git a/src/i830.h b/src/i830.h
index 4794169..d9adfbf 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -724,6 +724,7 @@ typedef struct _I830Rec {
    enum last_3d *last_3d;
 
    Bool use_drm_mode;
+   Bool kernel_exec_fencing;
 #ifdef XF86DRM_MODE
    drmmode_rec drmmode;
    int drm_mm_init;
@@ -910,6 +911,9 @@ extern void i830WaitSync(ScrnInfoPtr pScrn);
 /* i830_memory.c */
 Bool i830_bind_all_memory(ScrnInfoPtr pScrn);
 Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
+unsigned long i830_get_fence_size(I830Ptr pI830, unsigned long size);
+unsigned long i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format);
+unsigned long i830_get_fence_alignment(I830Ptr pI830, unsigned long size);
 
 Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
diff --git a/src/i830_dri.c b/src/i830_dri.c
index d6698da..7a95d02 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1570,7 +1570,7 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
 					       pDraw->depth, 0);
 	    switch (attachments[i]) {
 	    case DRI2BufferDepth:
-		if (IS_I965G(pI830))
+		if (SUPPORTS_YTILING(pI830))
 		    tiling = I915_TILING_Y;
 		else
 		    tiling = I915_TILING_X;
@@ -1583,19 +1583,14 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
 		break;
 	    }
 
-	    /* Disable tiling on 915-class 3D for now.  Because the 2D blitter
-	     * requires fence regs to operate, and they're not being managed
-	     * by the kernel yet, we don't want to expose tiled buffers to the
-	     * 3D client as it'll just render incorrectly if it pays attention
-	     * to our tiling bits at all.
-	     */
-	    if (!IS_I965G(pI830))
+	    if (!pI830->tiling ||
+		(!IS_I965G(pI830) && !pI830->kernel_exec_fencing))
 		tiling = I915_TILING_NONE;
 
 	    if (tiling != I915_TILING_NONE) {
 		bo = i830_get_pixmap_bo(pPixmap);
 		drm_intel_bo_set_tiling(bo, &tiling,
-					pDraw->width * pDraw->bitsPerPixel / 8);
+					intel_get_pixmap_pitch(pPixmap));
 	    }
 	}
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index bf5ecc4..2c4ea07 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1822,6 +1822,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
    pI830->SaveGeneration = -1;
    pI830->pEnt = pEnt;
    pI830->use_drm_mode = drm_mode_setting;
+   pI830->kernel_exec_fencing = pI830->use_drm_mode;
 
    if (!I830LoadSyms(pScrn))
        return FALSE;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 9249074..28be786 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -882,11 +882,25 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag
     
     if (w && h)
     {
+	unsigned int size;
+
 	stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
 			  i830->accel_pixmap_pitch_alignment);
-    
-	bo = dri_bo_alloc (i830->bufmgr, "pixmap", stride * h, 
-			   i830->accel_pixmap_offset_alignment);
+
+	/* Use the I915_FENCE_TILING_X even if it may end up being TILING_Y,
+	 * as it just results in larger alignment.  Really, we need to use the
+	 * usage hint to tell what the pixmap's going to be.
+	 */
+	stride = i830_get_fence_pitch(i830, stride, I915_TILING_X);
+	/* Round the object up to the size of the fence it will live in
+	 * if necessary.  We could potentially make the kernel allocate
+	 * a larger aperture space and just bind the subset of pages in,
+	 * but this is easier and also keeps us out of trouble (as much)
+	 * with drm_intel_bufmgr_check_aperture().
+	 */
+	size = i830_get_fence_size(i830, stride * h);
+
+	bo = dri_bo_alloc (i830->bufmgr, "pixmap", size, 0);
 	if (!bo) {
 	    fbDestroyPixmap (pixmap);
 	    return NullPixmap;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 9bfee81..f3c55a3 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -132,10 +132,9 @@ static void i830_clear_tiling(ScrnInfoPtr pScrn, unsigned int fence_nr);
 /**
  * Returns the fence size for a tiled area of the given size.
  */
-static unsigned long
-i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size)
+unsigned long
+i830_get_fence_size(I830Ptr pI830, unsigned long size)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
     unsigned long i;
     unsigned long start;
 
@@ -158,6 +157,43 @@ i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size)
     }
 }
 
+/**
+ * On some chips, pitch width has to be a power of two tile width, so
+ * calculate that here.
+ */
+unsigned long
+i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format)
+{
+    unsigned long i;
+    unsigned long tile_width = (format == I915_TILING_Y) ? 128 : 512;
+
+    if (format == TILE_NONE)
+	return pitch;
+
+    /* 965 is flexible */
+    if (IS_I965G(pI830))
+	return ROUND_TO(pitch, tile_width);
+
+    /* Pre-965 needs power of two tile width */
+    for (i = tile_width; i < pitch; i <<= 1)
+	;
+
+    return i;
+}
+
+/**
+ * On some chips, pitch width has to be a power of two tile width, so
+ * calculate that here.
+ */
+unsigned long
+i830_get_fence_alignment(I830Ptr pI830, unsigned long size)
+{
+    if (IS_I965G(pI830))
+	return 4096;
+    else
+	return i830_get_fence_size(pI830, size);
+}
+
 static Bool
 i830_check_display_stride(ScrnInfoPtr pScrn, int stride, Bool tiling)
 {
@@ -388,6 +424,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 #ifdef XF86DRI
     int dri_major, dri_minor, dri_patch;
     struct drm_i915_getparam gp;
+    struct drm_i915_setparam sp;
     int has_gem;
     int has_dri;
 #endif
@@ -499,6 +536,18 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 		struct drm_i915_gem_init init;
 		int ret;
 
+		sp.param = I915_SETPARAM_NUM_USED_FENCES;
+		if (pI830->use_drm_mode)
+		    sp.value = 0; /* kernel gets them all */
+		else if (pI830->directRenderingType == DRI_XF86DRI)
+		    sp.value = 3; /* front/back/depth */
+		else
+		    sp.value = 2; /* just front for DRI2 (both old & new though) */
+		ret = drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM, &sp,
+				      sizeof(sp));
+		if (ret == 0)
+		    pI830->kernel_exec_fencing = TRUE;
+
 		init.gtt_start = pI830->memory_manager->offset;
 		init.gtt_end = pI830->memory_manager->offset +
 		    pI830->memory_manager->size;
@@ -769,7 +818,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
 
     /* Only allocate page-sized increments. */
     size = ALIGN(size, GTT_PAGE_SIZE);
-    align = ROUND_TO(align, GTT_PAGE_SIZE);
+    align = i830_get_fence_alignment(pI830, size);
 
     mem = xcalloc(1, sizeof(*mem));
     if (mem == NULL)
@@ -814,7 +863,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
 	break;
     }
 
-    ret = dri_bo_set_tiling(mem->bo, &bo_tiling_mode);
+    ret = drm_intel_bo_set_tiling(mem->bo, &bo_tiling_mode, pitch);
     if (ret != 0 || (bo_tiling_mode == I915_TILING_NONE && tile_format != TILE_NONE)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Failed to set tiling on %s: %s\n",
@@ -887,16 +936,8 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
 	}
 
 	/* round to size necessary for the fence register to work */
-	size = i830_get_fence_size(pScrn, size);
-	if (IS_I965G(pI830)) {
-	    if (alignment < GTT_PAGE_SIZE)
-		alignment = GTT_PAGE_SIZE;
-	} else {
-	    /* The offset has to be aligned to at least the size of the fence
-	     * region.
-	     */
-	    alignment = size;
-	}
+	size = i830_get_fence_size(pI830, size);
+	alignment = i830_get_fence_alignment(pI830, size);
     }
 #ifdef XF86DRI
     if (pI830->use_drm_mode || (pI830->memory_manager &&


More information about the xorg-commit mailing list