[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 configure.ac                 |    1 
 src/intel_dri.c              |   90 -
 src/intel_glamor.c           |    2 
 src/intel_shadow.c           |   24 
 src/intel_uxa.c              |    6 
 src/sna/blt.c                |    2 
 src/sna/gen2_render.c        |  121 -
 src/sna/gen3_render.c        |  230 +-
 src/sna/gen4_render.c        |  175 +-
 src/sna/gen5_render.c        |  201 +-
 src/sna/gen6_render.c        |  418 +++-
 src/sna/gen6_render.h        |   19 
 src/sna/gen7_render.c        |  456 +++--
 src/sna/gen7_render.h        |    2 
 src/sna/kgem.c               | 1133 ++++++++-----
 src/sna/kgem.h               |  122 +
 src/sna/kgem_debug_gen5.c    |    2 
 src/sna/sna.h                |   43 
 src/sna/sna_accel.c          | 3701 +++++++++++++++++++++++++++++++------------
 src/sna/sna_blt.c            |  112 -
 src/sna/sna_composite.c      |   30 
 src/sna/sna_damage.c         |  218 +-
 src/sna/sna_damage.h         |   27 
 src/sna/sna_dri.c            |   41 
 src/sna/sna_driver.c         |    3 
 src/sna/sna_glyphs.c         |   28 
 src/sna/sna_gradient.c       |    8 
 src/sna/sna_io.c             |  557 +++++-
 src/sna/sna_render.c         |  655 +++++--
 src/sna/sna_render.h         |    9 
 src/sna/sna_render_inline.h  |   13 
 src/sna/sna_tiling.c         |  120 +
 src/sna/sna_trapezoids.c     |    9 
 src/sna/sna_video.c          |    2 
 src/sna/sna_video_hwmc.c     |    5 
 src/sna/sna_video_textured.c |   43 
 36 files changed, 6078 insertions(+), 2550 deletions(-)

New commits:
commit 4774c6b8331831e0c9f3b24f5f6e1b6ea399f628
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Feb 2 15:23:03 2012 +0000

    sna: Add a couple of sanity checks that the CPU drawable is on the CPU
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 71d3f06..1d2b999 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1070,7 +1070,8 @@ done:
 		DBG(("%s: syncing CPU bo\n", __FUNCTION__));
 		kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
 	}
-
+	assert(pixmap->devPrivate.ptr);
+	assert(pixmap->devKind);
 	return true;
 }
 
@@ -1534,6 +1535,8 @@ out:
 		DBG(("%s: syncing cpu bo\n", __FUNCTION__));
 		kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
 	}
+	assert(pixmap->devPrivate.ptr);
+	assert(pixmap->devKind);
 	return true;
 }
 

commit 418cd98db7c4a2886c9e310f3691eb6c77421dd7
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Feb 1 19:10:41 2012 +0000

    sna/gen6: Ring switching outweighs the benefits for cairo-traces
    
    At the moment, the jury is still out on whether freely switching rings
    for fills is a Good Idea. So make it easier to turn it on and off for
    testing.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index ec5412a..9f799ef 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -57,6 +57,8 @@
 #define NO_FILL_BOXES 0
 #define NO_CLEAR 0
 
+#define NO_RING_SWITCH 1
+
 #define GEN6_MAX_SIZE 8192
 
 static const uint32_t ps_kernel_nomask_affine[][4] = {
@@ -2215,6 +2217,11 @@ static bool prefer_blt_ring(struct sna *sna)
 	return sna->kgem.ring != KGEM_RENDER;
 }
 
+static bool can_switch_rings(struct sna *sna)
+{
+	return sna->kgem.has_semaphores && !NO_RING_SWITCH;
+}
+
 static bool
 is_solid(PicturePtr picture)
 {
@@ -2252,7 +2259,7 @@ try_blt(struct sna *sna,
 		return TRUE;
 	}
 
-	if (sna->kgem.has_semaphores) {
+	if (can_switch_rings(sna)) {
 		if (is_solid(src))
 			return TRUE;
 	}
@@ -3432,7 +3439,9 @@ gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op)
 static inline bool prefer_blt_fill(struct sna *sna,
 				   struct kgem_bo *bo)
 {
-	return sna->kgem.has_semaphores || prefer_blt_ring(sna) || untiled_tlb_miss(bo);
+	return (can_switch_rings(sna) ||
+		prefer_blt_ring(sna) ||
+		untiled_tlb_miss(bo));
 }
 
 static Bool

commit 2d0e7c7ecd7371ac7b5fe3f382fc5d04792f7019
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Feb 1 14:52:56 2012 +0000

    sna: Search again for a just-large-enough mapping for inplace uploads
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b446558..d2580e6 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -104,6 +104,8 @@ static inline void list_replace(struct list *old,
 #endif
 
 #define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
+#define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE)
+
 #define MAX_GTT_VMA_CACHE 512
 #define MAX_CPU_VMA_CACHE INT16_MAX
 #define MAP_PRESERVE_TIME 10
@@ -3215,6 +3217,8 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 			old = search_linear_cache(kgem, alloc, CREATE_CPU_MAP);
 		if (old == NULL)
 			old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP);
+		if (old == NULL)
+			old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_INACTIVE | CREATE_CPU_MAP);
 		if (old) {
 			DBG(("%s: reusing handle=%d for buffer\n",
 			     __FUNCTION__, old->handle));
@@ -3290,6 +3294,9 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 			}
 		}
 #endif
+		if (old == NULL)
+			old = search_linear_cache(kgem, NUM_PAGES(size),
+						  CREATE_INACTIVE | CREATE_GTT_MAP);
 		if (old) {
 			DBG(("%s: reusing handle=%d for buffer\n",
 			     __FUNCTION__, old->handle));

commit 55c7088f54655609fbb00106679a566b46ee8dba
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Feb 1 01:33:52 2012 +0000

    sna: Add debugging code to verify damage extents of fallback paths
    
    After using the CPU, upload the damage and read back the pixels from the
    GPU bo and verify that the two are equivalent.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 40748ec..71d3f06 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -80,12 +80,68 @@
 #define ACCEL_POLY_FILL_ARC 1
 #define ACCEL_POLY_TEXT8 1
 #define ACCEL_POLY_TEXT16 1
+#define ACCEL_POLY_GLYPH 1
 #define ACCEL_IMAGE_TEXT8 1
 #define ACCEL_IMAGE_TEXT16 1
 #define ACCEL_IMAGE_GLYPH 1
-#define ACCEL_POLY_GLYPH 1
 #define ACCEL_PUSH_PIXELS 1
 
+#if 0
+static void __sna_fallback_flush(DrawablePtr d)
+{
+	PixmapPtr pixmap = get_drawable_pixmap(d);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	struct sna_pixmap *priv;
+	BoxRec box;
+	PixmapPtr tmp;
+	int i, j;
+	char *src, *dst;
+
+	DBG(("%s: uploading CPU damage...\n", __FUNCTION__));
+	priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ);
+	if (priv == NULL)
+		return;
+
+	DBG(("%s: downloading GPU damage...\n", __FUNCTION__));
+	if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
+		return;
+
+	box.x1 = box.y1 = 0;
+	box.x2 = pixmap->drawable.width;
+	box.y2 = pixmap->drawable.height;
+
+	tmp = fbCreatePixmap(pixmap->drawable.pScreen,
+			     pixmap->drawable.width,
+			     pixmap->drawable.height,
+			     pixmap->drawable.depth,
+			     0);
+
+	DBG(("%s: comparing with direct read...\n", __FUNCTION__));
+	sna_read_boxes(sna,
+		       priv->gpu_bo, 0, 0,
+		       tmp, 0, 0,
+		       &box, 1);
+
+	src = pixmap->devPrivate.ptr;
+	dst = tmp->devPrivate.ptr;
+	for (i = 0; i < tmp->drawable.height; i++) {
+		if (memcmp(src, dst, tmp->drawable.width * tmp->drawable.bitsPerPixel >> 3)) {
+			for (j = 0; src[j] == dst[j]; j++)
+				;
+			ErrorF("mismatch at (%d, %d)\n",
+			       8*j / tmp->drawable.bitsPerPixel, i);
+			abort();
+		}
+		src += pixmap->devKind;
+		dst += tmp->devKind;
+	}
+	fbDestroyPixmap(tmp);
+}
+#define FALLBACK_FLUSH(d) __sna_fallback_flush(d)
+#else
+#define FALLBACK_FLUSH(d)
+#endif
+
 static int sna_font_key;
 
 static const uint8_t copy_ROP[] = {
@@ -1453,8 +1509,9 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	}
 
 done:
-	if (flags & MOVE_WRITE && !DAMAGE_IS_ALL(priv->cpu_damage)) {
+	if (flags & MOVE_WRITE) {
 		DBG(("%s: applying cpu damage\n", __FUNCTION__));
+		assert(!DAMAGE_IS_ALL(priv->cpu_damage));
 		assert_pixmap_contains_box(pixmap, RegionExtents(region));
 		sna_damage_add(&priv->cpu_damage, region);
 		if (priv->gpu_bo &&
@@ -2982,6 +3039,7 @@ fallback:
 	DBG(("%s: fbPutImage(%d, %d, %d, %d)\n",
 	     __FUNCTION__, x, y, w, h));
 	fbPutImage(drawable, gc, depth, x, y, w, h, left, format, bits);
+	FALLBACK_FLUSH(drawable);
 out:
 	RegionUninit(&region);
 }
@@ -3694,6 +3752,7 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				  src_x, src_y,
 				  width, height,
 				  dst_x, dst_y);
+		FALLBACK_FLUSH(dst);
 out:
 		RegionUninit(&region);
 		return ret;
@@ -4625,6 +4684,7 @@ fallback:
 
 	DBG(("%s: fbFillSpans\n", __FUNCTION__));
 	fbFillSpans(drawable, gc, n, pt, width, sorted);
+	FALLBACK_FLUSH(drawable);
 out:
 	RegionUninit(&region);
 }
@@ -4663,6 +4723,7 @@ fallback:
 
 	DBG(("%s: fbSetSpans\n", __FUNCTION__));
 	fbSetSpans(drawable, gc, src, pt, width, n, sorted);
+	FALLBACK_FLUSH(drawable);
 out:
 	RegionUninit(&region);
 }
@@ -5137,6 +5198,7 @@ fallback:
 	DBG(("%s: fbCopyPlane(%d, %d, %d, %d, %d,%d) %x\n",
 	     __FUNCTION__, src_x, src_y, w, h, dst_x, dst_y, (unsigned)bit));
 	ret = fbCopyPlane(src, dst, gc, src_x, src_y, w, h, dst_x, dst_y, bit);
+	FALLBACK_FLUSH(dst);
 out:
 	RegionUninit(&region);
 	return ret;
@@ -5336,6 +5398,7 @@ fallback:
 
 	DBG(("%s: fbPolyPoint\n", __FUNCTION__));
 	fbPolyPoint(drawable, gc, mode, n, pt);
+	FALLBACK_FLUSH(drawable);
 out:
 	RegionUninit(&region);
 }
@@ -6389,6 +6452,7 @@ fallback:
 
 	DBG(("%s: fbPolyLine\n", __FUNCTION__));
 	fbPolyLine(drawable, gc, mode, n, pt);
+	FALLBACK_FLUSH(drawable);
 
 	gc->ops = (GCOps *)&sna_gc_ops;
 out:
@@ -7301,6 +7365,7 @@ fallback:
 
 	DBG(("%s: fbPolySegment\n", __FUNCTION__));
 	fbPolySegment(drawable, gc, n, seg);
+	FALLBACK_FLUSH(drawable);
 
 	gc->ops = (GCOps *)&sna_gc_ops;
 out:
@@ -7850,6 +7915,7 @@ fallback:
 
 	DBG(("%s: fbPolyRectangle\n", __FUNCTION__));
 	fbPolyRectangle(drawable, gc, n, r);
+	FALLBACK_FLUSH(drawable);
 out:
 	RegionUninit(&region);
 }
@@ -8027,6 +8093,7 @@ fallback:
 
 	DBG(("%s -- fbPolyArc\n", __FUNCTION__));
 	fbPolyArc(drawable, gc, n, arc);
+	FALLBACK_FLUSH(drawable);
 
 	gc->ops = (GCOps *)&sna_gc_ops;
 out:
@@ -9792,6 +9859,7 @@ fallback:
 			}
 		} while (--n);
 	}
+	FALLBACK_FLUSH(draw);
 out:
 	RegionUninit(&region);
 }
@@ -10332,6 +10400,7 @@ force_fallback:
 		DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
 		fbPolyGlyphBlt(drawable, gc, x, y, n,
 			       info, FONTGLYPHS(gc->font));
+		FALLBACK_FLUSH(drawable);
 	}
 out:
 	RegionUninit(&region);
@@ -10420,6 +10489,7 @@ force_fallback:
 		DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
 		fbPolyGlyphBlt(drawable, gc, x, y, n,
 			       info, FONTGLYPHS(gc->font));
+		FALLBACK_FLUSH(drawable);
 	}
 out:
 	RegionUninit(&region);
@@ -10517,6 +10587,7 @@ force_fallback:
 		DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
 		fbImageGlyphBlt(drawable, gc, x, y, n,
 				info, FONTGLYPHS(gc->font));
+		FALLBACK_FLUSH(drawable);
 	}
 out:
 	RegionUninit(&region);
@@ -10607,6 +10678,7 @@ force_fallback:
 		DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
 		fbImageGlyphBlt(drawable, gc, x, y, n,
 				info, FONTGLYPHS(gc->font));
+		FALLBACK_FLUSH(drawable);
 	}
 out:
 	RegionUninit(&region);
@@ -10869,6 +10941,7 @@ fallback:
 
 	DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
 	fbImageGlyphBlt(drawable, gc, x, y, n, info, base);
+	FALLBACK_FLUSH(drawable);
 
 out:
 	RegionUninit(&region);
@@ -10943,6 +11016,7 @@ fallback:
 
 	DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
 	fbPolyGlyphBlt(drawable, gc, x, y, n, info, base);
+	FALLBACK_FLUSH(drawable);
 
 out:
 	RegionUninit(&region);
@@ -11123,6 +11197,7 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
 	DBG(("%s: fallback, fbPushPixels(%d, %d, %d %d)\n",
 	     __FUNCTION__, w, h, x, y));
 	fbPushPixels(gc, bitmap, drawable, w, h, x, y);
+	FALLBACK_FLUSH(drawable);
 out:
 	RegionUninit(&region);
 }
diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index ab825aa..f52ecac 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -514,8 +514,7 @@ static void __sna_damage_reduce(struct sna_damage *damage)
 		damage->extents = region->extents;
 	}
 
-	if (free_boxes)
-		free(boxes);
+	free(free_boxes);
 
 done:
 	damage->mode = DAMAGE_ADD;
@@ -1048,6 +1047,7 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
 					       &damage->region,
 					       region);
 			damage->extents = damage->region.extents;
+			assert(pixman_region_not_empty(&damage->region));
 			return damage;
 		}
 

commit c8fc2cde53ef7aa011ec7c47e7fc5486de0651f5
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Feb 1 01:27:43 2012 +0000

    sna: Fill extents for ImageGlyphs
    
    The spec says to fill the characters boxes, which is what the hardware
    does. The implementation fills the extents instead. rxvt expects the
    former, emacs the latter. Overdraw is a nuisance, but less than leaving
    glyphs behind...
    
    Reported-by: walch.martin@web.de
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45438
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index a0ea54f..9df8cfd 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -359,7 +359,8 @@ to_sna_from_kgem(struct kgem *kgem)
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #endif
 #define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#define MIN(a,b)	((a) <= (b) ? (a) : (b))
+#define MAX(a,b)	((a) >= (b) ? (a) : (b))
 
 extern xf86CrtcPtr sna_covering_crtc(ScrnInfoPtr scrn,
 				     const BoxRec *box,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 4148bdb..40748ec 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -10011,6 +10011,11 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	extents = REGION_RECTS(clip);
 	last_extents = extents + REGION_NUM_RECTS(clip);
 
+	if (bg != -1) /* emulate miImageGlyphBlt */
+		sna_blt_fill_boxes(sna, GXcopy,
+				   bo, drawable->bitsPerPixel,
+				   bg, extents, REGION_NUM_RECTS(clip));
+
 	kgem_set_mode(&sna->kgem, KGEM_BLT);
 	if (!kgem_check_batch(&sna->kgem, 16) ||
 	    !kgem_check_bo_fenced(&sna->kgem, bo, NULL) ||
@@ -10174,6 +10179,8 @@ sna_glyph_extents(FontPtr font,
 
 		extents->overallWidth += p->metrics.characterWidth;
 	}
+
+	assert(extents->overallWidth > 0);
 }
 
 static bool sna_set_glyph(CharInfoPtr in, CharInfoPtr out)
@@ -10458,10 +10465,17 @@ sna_image_text8(DrawablePtr drawable, GCPtr gc,
 		return;
 
 	sna_glyph_extents(gc->font, info, n, &extents);
-	region.extents.x1 = x + extents.overallLeft;
-	region.extents.y1 = y - extents.overallAscent;
-	region.extents.x2 = x + extents.overallRight;
-	region.extents.y2 = y + extents.overallDescent;
+	region.extents.x1 = x + MIN(0, extents.overallLeft);
+	region.extents.y1 = y - extents.fontAscent;
+	region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight);
+	region.extents.y2 = y + extents.fontDescent;
+
+	DBG(("%s: count=%ld/%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n",
+	     __FUNCTION__, n, count,
+	     extents.overallLeft, extents.overallRight, extents.overallWidth,
+	     extents.fontAscent, extents.fontDescent,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	translate_box(&region.extents, drawable);
 	clip_box(&region.extents, gc);
@@ -10473,6 +10487,11 @@ sna_image_text8(DrawablePtr drawable, GCPtr gc,
 	if (!RegionNotEmpty(&region))
 		return;
 
+	DBG(("%s: clipped extents (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
+
 	if (FORCE_FALLBACK)
 		goto force_fallback;
 
@@ -10535,10 +10554,17 @@ sna_image_text16(DrawablePtr drawable, GCPtr gc,
 		return;
 
 	sna_glyph_extents(gc->font, info, n, &extents);
-	region.extents.x1 = x + extents.overallLeft;
-	region.extents.y1 = y - extents.overallAscent;
-	region.extents.x2 = x + extents.overallRight;
-	region.extents.y2 = y + extents.overallDescent;
+	region.extents.x1 = x + MIN(0, extents.overallLeft);
+	region.extents.y1 = y - extents.fontAscent;
+	region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight);
+	region.extents.y2 = y + extents.fontDescent;
+
+	DBG(("%s: count=%ld/%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n",
+	     __FUNCTION__, n, count,
+	     extents.overallLeft, extents.overallRight, extents.overallWidth,
+	     extents.fontAscent, extents.fontDescent,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	translate_box(&region.extents, drawable);
 	clip_box(&region.extents, gc);
@@ -10550,6 +10576,11 @@ sna_image_text16(DrawablePtr drawable, GCPtr gc,
 	if (!RegionNotEmpty(&region))
 		return;
 
+	DBG(("%s: clipped extents (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
+
 	if (FORCE_FALLBACK)
 		goto force_fallback;
 
@@ -10625,6 +10656,11 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	extents = REGION_RECTS(clip);
 	last_extents = extents + REGION_NUM_RECTS(clip);
 
+	if (bg != -1) /* emulate miImageGlyphBlt */
+		sna_blt_fill_boxes(sna, GXcopy,
+				   bo, drawable->bitsPerPixel,
+				   bg, extents, REGION_NUM_RECTS(clip));
+
 	kgem_set_mode(&sna->kgem, KGEM_BLT);
 	if (!kgem_check_batch(&sna->kgem, 16) ||
 	    !kgem_check_bo_fenced(&sna->kgem, bo, NULL) ||
@@ -10775,11 +10811,18 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 	if (n == 0)
 		return;
 
-	QueryGlyphExtents(gc->font, info, n, &extents);
-	region.extents.x1 = x + extents.overallLeft;
-	region.extents.y1 = y - extents.overallAscent;
-	region.extents.x2 = x + extents.overallRight;
-	region.extents.y2 = y + extents.overallDescent;
+	sna_glyph_extents(gc->font, info, n, &extents);
+	region.extents.x1 = x + MIN(0, extents.overallLeft);
+	region.extents.y1 = y - extents.fontAscent;
+	region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight);
+	region.extents.y2 = y + extents.fontDescent;
+
+	DBG(("%s: count=%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n",
+	     __FUNCTION__, n,
+	     extents.overallLeft, extents.overallRight, extents.overallWidth,
+	     extents.fontAscent, extents.fontDescent,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 
 	translate_box(&region.extents, drawable);
 	clip_box(&region.extents, gc);
@@ -10847,7 +10890,7 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 	if (n == 0)
 		return;
 
-	QueryGlyphExtents(gc->font, info, n, &extents);
+	sna_glyph_extents(gc->font, info, n, &extents);
 	region.extents.x1 = x + extents.overallLeft;
 	region.extents.y1 = y - extents.overallAscent;
 	region.extents.x2 = x + extents.overallRight;

commit 13508ab5ea136caca90c846ff1026c0c1acd2ad5
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jan 31 22:38:46 2012 +0000

    sna: PolyGlyph supports all of fill/tile/stipple rules
    
    The hw routines only directly supports solid fill so fallback for the
    interesting cases. An alternative would be to investigate using the
    miPolyGlyph routine to convert the weird fills into spans in order to
    fallback. Sounds cheaper to fallback, so wait for an actual use case.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index cccdd59..b446558 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -719,11 +719,10 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 
 	DBG(("%s: large object thresold=%d\n",
 	     __FUNCTION__, kgem->large_object_size));
-	DBG(("%s: max object size (gpu=%d, cpu=%d, tile=%d)\n",
+	DBG(("%s: max object size (gpu=%d, cpu=%d, tile upload=%d, copy=%d)\n",
 	     __FUNCTION__,
-	     kgem->max_gpu_size,
-	     kgem->max_cpu_size,
-	     kgem->max_tile_size));
+	     kgem->max_gpu_size, kgem->max_cpu_size,
+	     kgem->max_upload_tile_size, kgem->max_copy_tile_size));
 
 	/* Convert the aperture thresholds to pages */
 	kgem->aperture_low /= PAGE_SIZE;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 3115bd7..4148bdb 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -9968,7 +9968,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	      int _x, int _y, unsigned int _n,
 	      CharInfoPtr *_info,
 	      RegionRec *clip,
-	      bool transparent)
+	      uint32_t fg, uint32_t bg)
 {
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
 	struct sna *sna = to_sna_from_pixmap(pixmap);
@@ -9979,10 +9979,10 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	int16_t dx, dy;
 	uint32_t br00;
 
-	uint8_t rop = transparent ? copy_ROP[gc->alu] : ROP_S;
+	uint8_t rop = bg == -1 ? copy_ROP[gc->alu] : ROP_S;
 
-	DBG(("%s (%d, %d) x %d, transparent? %d, alu=%d\n",
-	     __FUNCTION__, _x, _y, _n, transparent, rop));
+	DBG(("%s (%d, %d) x %d, fg=%08x, bg=%08x alu=%02x\n",
+	     __FUNCTION__, _x, _y, _n, fg, bg, rop));
 
 	if (wedged(sna)) {
 		DBG(("%s -- fallback, wedged\n", __FUNCTION__));
@@ -10025,7 +10025,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 		b[0] |= BLT_DST_TILED;
 		b[1] >>= 2;
 	}
-	b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
+	b[1] |= 1 << 30 | (bg == -1) << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
 	b[2] = extents->y1 << 16 | extents->x1;
 	b[3] = extents->y2 << 16 | extents->x2;
 	b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo,
@@ -10033,8 +10033,8 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 			      I915_GEM_DOMAIN_RENDER |
 			      KGEM_RELOC_FENCED,
 			      0);
-	b[5] = gc->bgPixel;
-	b[6] = gc->fgPixel;
+	b[5] = bg;
+	b[6] = fg;
 	b[7] = 0;
 	sna->kgem.nbatch += 8;
 
@@ -10079,7 +10079,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 					b[0] |= BLT_DST_TILED;
 					b[1] >>= 2;
 				}
-				b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
+				b[1] |= 1 << 30 | (bg == -1) << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
 				b[2] = extents->y1 << 16 | extents->x1;
 				b[3] = extents->y2 << 16 | extents->x2;
 				b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo,
@@ -10087,8 +10087,8 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 						      I915_GEM_DOMAIN_RENDER |
 						      KGEM_RELOC_FENCED,
 						      0);
-				b[5] = gc->bgPixel;
-				b[6] = gc->fgPixel;
+				b[5] = bg;
+				b[6] = fg;
 				b[7] = 0;
 				sna->kgem.nbatch += 8;
 			}
@@ -10269,6 +10269,7 @@ sna_poly_text8(DrawablePtr drawable, GCPtr gc,
 	ExtentInfoRec extents;
 	RegionRec region;
 	long unsigned i, n;
+	uint32_t fg;
 
 	if (drawable->depth < 8)
 		goto fallback;
@@ -10302,7 +10303,13 @@ sna_poly_text8(DrawablePtr drawable, GCPtr gc,
 	if (!ACCEL_POLY_TEXT8)
 		goto force_fallback;
 
-	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, true)) {
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		return false;
+
+	if (!gc_is_solid(gc, &fg))
+		goto force_fallback;
+
+	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, fg, -1)) {
 force_fallback:
 		DBG(("%s: fallback\n", __FUNCTION__));
 		gc->font->get_glyphs(gc->font, count, (unsigned char *)chars,
@@ -10350,6 +10357,7 @@ sna_poly_text16(DrawablePtr drawable, GCPtr gc,
 	ExtentInfoRec extents;
 	RegionRec region;
 	long unsigned i, n;
+	uint32_t fg;
 
 	if (drawable->depth < 8)
 		goto fallback;
@@ -10383,7 +10391,13 @@ sna_poly_text16(DrawablePtr drawable, GCPtr gc,
 	if (!ACCEL_POLY_TEXT16)
 		goto force_fallback;
 
-	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, true)) {
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		return false;
+
+	if (!gc_is_solid(gc, &fg))
+		goto force_fallback;
+
+	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, fg, -1)) {
 force_fallback:
 		DBG(("%s: fallback\n", __FUNCTION__));
 		gc->font->get_glyphs(gc->font, count, (unsigned char *)chars,
@@ -10465,7 +10479,10 @@ sna_image_text8(DrawablePtr drawable, GCPtr gc,
 	if (!ACCEL_IMAGE_TEXT8)
 		goto force_fallback;
 
-	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, false)) {
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		goto force_fallback;
+
+	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, gc->fgPixel, gc->bgPixel)) {
 force_fallback:
 		DBG(("%s: fallback\n", __FUNCTION__));
 		gc->font->get_glyphs(gc->font, count, (unsigned char *)chars,
@@ -10539,7 +10556,10 @@ sna_image_text16(DrawablePtr drawable, GCPtr gc,
 	if (!ACCEL_IMAGE_TEXT16)
 		goto force_fallback;
 
-	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, false)) {
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		goto force_fallback;
+
+	if (!sna_glyph_blt(drawable, gc, x, y, n, info, &region, gc->fgPixel, gc->bgPixel)) {
 force_fallback:
 		DBG(("%s: fallback\n", __FUNCTION__));
 		gc->font->get_glyphs(gc->font, count, (unsigned char *)chars,
@@ -10580,14 +10600,14 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 		       struct kgem_bo *bo,
 		       struct sna_damage **damage,
 		       RegionPtr clip,
-		       bool transparent)
+		       uint32_t fg, uint32_t bg)
 {
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 	const BoxRec *extents, *last_extents;
 	uint32_t *b;
 	int16_t dx, dy;
-	uint8_t rop = transparent ? copy_ROP[gc->alu] : ROP_S;
+	uint8_t rop = bg == -1 ? copy_ROP[gc->alu] : ROP_S;
 
 	if (bo->tiling == I915_TILING_Y) {
 		DBG(("%s: converting bo from Y-tiling\n", __FUNCTION__));
@@ -10619,7 +10639,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 		b[0] |= BLT_DST_TILED;
 		b[1] >>= 2;
 	}
-	b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
+	b[1] |= 1 << 30 | (bg == -1) << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
 	b[2] = extents->y1 << 16 | extents->x1;
 	b[3] = extents->y2 << 16 | extents->x2;
 	b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo,
@@ -10627,8 +10647,8 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 			      I915_GEM_DOMAIN_RENDER |
 			      KGEM_RELOC_FENCED,
 			      0);
-	b[5] = gc->bgPixel;
-	b[6] = gc->fgPixel;
+	b[5] = bg;
+	b[6] = fg;
 	b[7] = 0;
 	sna->kgem.nbatch += 8;
 
@@ -10672,7 +10692,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 					b[0] |= BLT_DST_TILED;
 					b[1] >>= 2;
 				}
-				b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
+				b[1] |= 1 << 30 | (bg == -1) << 29 | blt_depth(drawable->depth) << 24 | rop << 16;
 				b[2] = extents->y1 << 16 | extents->x1;
 				b[3] = extents->y2 << 16 | extents->x2;
 				b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
@@ -10681,8 +10701,8 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 						      I915_GEM_DOMAIN_RENDER |
 						      KGEM_RELOC_FENCED,
 						      0);
-				b[5] = gc->bgPixel;
-				b[6] = gc->fgPixel;
+				b[5] = bg;
+				b[6] = fg;
 				b[7] = 0;
 				sna->kgem.nbatch += 8;
 			}
@@ -10786,9 +10806,13 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 		goto fallback;
 	}
 
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		goto fallback;
+
 	if ((bo = sna_drawable_use_bo(drawable, &region.extents, &damage)) &&
 	    sna_reversed_glyph_blt(drawable, gc, x, y, n, info, base,
-				   bo, damage, &region, false))
+				   bo, damage, &region,
+				   gc->fgPixel, gc->bgPixel))
 		goto out;
 
 fallback:
@@ -10818,6 +10842,7 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 	RegionRec region;
 	struct sna_damage **damage;
 	struct kgem_bo *bo;
+	uint32_t fg;
 
 	if (n == 0)
 		return;
@@ -10853,9 +10878,15 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 		goto fallback;
 	}
 
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		goto fallback;
+
+	if (!gc_is_solid(gc, &fg))
+		goto fallback;
+
 	if ((bo = sna_drawable_use_bo(drawable, &region.extents, &damage)) &&
 	    sna_reversed_glyph_blt(drawable, gc, x, y, n, info, base,
-				   bo, damage, &region, true))
+				   bo, damage, &region, fg, -1))
 		goto out;
 
 fallback:

commit df4e1059a4e09998334dde6aa1c8ccfe76e442c0
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jan 31 19:19:13 2012 +0000

    sna/gen6: Prefer to do fills using the BLT
    
    Using the BLT is substantially faster than the current shaders for solid
    fill. The downside is that it invokes more ring switching.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 93410b6..ec5412a 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2210,12 +2210,23 @@ gen6_composite_set_target(struct sna *sna,
 	return TRUE;
 }
 
+static bool prefer_blt_ring(struct sna *sna)
+{
+	return sna->kgem.ring != KGEM_RENDER;
+}
+
+static bool
+is_solid(PicturePtr picture)
+{
+	return sna_picture_is_solid(picture, NULL);
+}
+
 static Bool
 try_blt(struct sna *sna,
 	PicturePtr dst, PicturePtr src,
 	int width, int height)
 {
-	if (sna->kgem.ring != KGEM_RENDER) {
+	if (prefer_blt_ring(sna)) {
 		DBG(("%s: already performing BLT\n", __FUNCTION__));
 		return TRUE;
 	}
@@ -2241,15 +2252,12 @@ try_blt(struct sna *sna,
 		return TRUE;
 	}
 
-	return FALSE;
-}
+	if (sna->kgem.has_semaphores) {
+		if (is_solid(src))
+			return TRUE;
+	}
 
-static bool
-is_solid(PicturePtr picture)
-{
-	return  picture->pDrawable->width == 1 &&
-		picture->pDrawable->height == 1 &&
-		picture->repeat;
+	return FALSE;
 }
 
 static bool
@@ -3071,7 +3079,7 @@ static inline bool prefer_blt_copy(struct sna *sna,
 				   struct kgem_bo *src_bo,
 				   struct kgem_bo *dst_bo)
 {
-	return (sna->kgem.ring != KGEM_RENDER ||
+	return (prefer_blt_ring(sna) ||
 		untiled_tlb_miss(src_bo) ||
 		untiled_tlb_miss(dst_bo));
 }
@@ -3424,7 +3432,7 @@ gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op)
 static inline bool prefer_blt_fill(struct sna *sna,
 				   struct kgem_bo *bo)
 {
-	return sna->kgem.ring != KGEM_RENDER || untiled_tlb_miss(bo);
+	return sna->kgem.has_semaphores || prefer_blt_ring(sna) || untiled_tlb_miss(bo);
 }
 
 static Bool

commit 8b012de0a1af4ec97c3197af3f1efdcc67bc2118
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Jan 31 20:29:58 2012 +0000

    sna/gen5: Always prefer to emit solid fills using the BLT
    
    As the BLT is far, far faster than using a shader.
    
    Improves cairo-demos/chart from 6 to 13 fps.
    
    Reported-by: Michael Larabel <Michael@phoronix.com>
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index dc1e720..03dc8c9 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1992,12 +1992,6 @@ picture_is_cpu(PicturePtr picture)
 	if (!picture->pDrawable)
 		return FALSE;
 
-	/* If it is a solid, try to use the render paths */
-	if (picture->pDrawable->width == 1 &&
-	    picture->pDrawable->height == 1 &&
-	    picture->repeat)
-		return FALSE;
-
 	if (too_large(picture->pDrawable->width, picture->pDrawable->height))
 		return TRUE;
 
@@ -2009,7 +2003,7 @@ try_blt(struct sna *sna,
 	PicturePtr dst, PicturePtr src,
 	int width, int height)
 {
-	if (sna->kgem.mode == KGEM_BLT) {
+	if (sna->kgem.mode != KGEM_RENDER) {
 		DBG(("%s: already performing BLT\n", __FUNCTION__));
 		return TRUE;
 	}
@@ -2023,6 +2017,10 @@ try_blt(struct sna *sna,
 	if (too_large(dst->pDrawable->width, dst->pDrawable->height))
 		return TRUE;
 
+	/* The blitter is much faster for solids */
+	if (sna_picture_is_solid(src, NULL))
+		return TRUE;
+
 	/* is the source picture only in cpu memory e.g. a shm pixmap? */
 	return picture_is_cpu(src);
 }
@@ -2733,13 +2731,18 @@ gen5_copy_bind_surfaces(struct sna *sna,
 	gen5_emit_state(sna, op, offset);


Reply to: