[Intel-gfx] [PATCH] support tiled rendering in 2D driver

Jesse Barnes jbarnes at virtuousgeek.org
Fri Jan 23 23:15:26 CET 2009


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.


-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/src/i830.h b/src/i830.h
index 4794169..f9444b1 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -969,6 +969,7 @@ i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform,
 				    float *x_out, float *y_out, float *z_out);
 
 void i830_enter_render(ScrnInfoPtr);
+unsigned long I830GetFencePitch(I830Ptr pI830, unsigned long pitch, int format);
 
 static inline void
 i830_wait_ring_idle(ScrnInfoPtr pScrn)
diff --git a/src/i830_dri.c b/src/i830_dri.c
index d6698da..72c8a38 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -1525,6 +1525,34 @@ I830DRIUnlock(ScrnInfoPtr pScrn)
 
 #ifdef DRI2
 
+/**
+ * On some chips, pitch width has to be a power of two tile width, so
+ * calculate that here.
+ */
+unsigned long
+I830GetFencePitch(I830Ptr pI830, unsigned long pitch, int format)
+{
+    unsigned long i;
+    unsigned long tile_width = 512;
+
+    if (IS_I965G(pI830)) {
+	/* 965 is flexible */
+	if (format == I915_TILING_Y)
+	    tile_width = 128;
+
+	return ROUND_TO(pitch, tile_width);
+    }
+
+    if (IS_I945GM(pI830) && format == I915_TILING_Y)
+	tile_width = 128;
+
+    /* Pre-965 needs power of two tile width */
+    for (i = tile_width; i < pitch; i <<= 1)
+	;
+
+    return ROUND_TO(pitch, i);
+}
+
 typedef struct {
     PixmapPtr pPixmap;
 } I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr;
@@ -1570,7 +1598,7 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
 					       pDraw->depth, 0);
 	    switch (attachments[i]) {
 	    case DRI2BufferDepth:
-		if (IS_I965G(pI830))
+		if (IS_I965G(pI830) || IS_I945GM(pI830))
 		    tiling = I915_TILING_Y;
 		else
 		    tiling = I915_TILING_X;
@@ -1583,19 +1611,15 @@ 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)
 		tiling = I915_TILING_NONE;
 
 	    if (tiling != I915_TILING_NONE) {
+		int pitch = (pDraw->width * pDraw->bitsPerPixel + 7) / 8;
+		int stride = I830GetFencePitch(pI830, pitch, tiling);
+
 		bo = i830_get_pixmap_bo(pPixmap);
-		drm_intel_bo_set_tiling(bo, &tiling,
-					pDraw->width * pDraw->bitsPerPixel / 8);
+		drm_intel_bo_set_tiling(bo, &tiling, stride);
 	    }
 	}
 
diff --git a/src/i830_exa.c b/src/i830_exa.c
index 9249074..3e487f9 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -872,7 +872,7 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag
     ScrnInfoPtr scrn = xf86Screens[screen->myNum];
     I830Ptr i830 = I830PTR(scrn);
     dri_bo *bo;
-    int stride;
+    int stride, align;
     PixmapPtr pixmap;
     
     if (w > 32767 || h > 32767)
@@ -884,9 +884,12 @@ i830_uxa_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usag
     {
 	stride = ROUND_TO((w * pixmap->drawable.bitsPerPixel + 7) / 8,
 			  i830->accel_pixmap_pitch_alignment);
+
+	stride = I830GetFencePitch(i830, stride, I915_TILING_X);
+
+	align = stride * h > 1024*1024 ? stride * h : 1024*1024;
     
-	bo = dri_bo_alloc (i830->bufmgr, "pixmap", stride * h, 
-			   i830->accel_pixmap_offset_alignment);
+	bo = dri_bo_alloc (i830->bufmgr, "pixmap", stride * h, align);
 	if (!bo) {
 	    fbDestroyPixmap (pixmap);
 	    return NullPixmap;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 9bfee81..7d55910 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -388,6 +388,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
@@ -495,6 +496,17 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size)
 				   TILE_NONE);
 
 	if (pI830->memory_manager != NULL) {
+	    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) */
+	    /* Don't care about failure, we'll just get slow rendering */
+	    drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM, &sp,
+			    sizeof(sp));
+
 	    if (!pI830->use_drm_mode) {
 		struct drm_i915_gem_init init;
 		int ret;
@@ -769,7 +781,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 = size > 1024*1024 ? size : 1024*1024;
 
     mem = xcalloc(1, sizeof(*mem));
     if (mem == NULL)
@@ -895,7 +907,7 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
 	    /* The offset has to be aligned to at least the size of the fence
 	     * region.
 	     */
-	    alignment = size;
+	    alignment = size > 1024*1024 ? size : 1024*1024;
 	}
     }
 #ifdef XF86DRI



More information about the Intel-gfx mailing list