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

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



 Makefile.am                                     |    8 
 NEWS                                            |   32 
 configure.ac                                    |   45 
 src/Makefile.am                                 |   27 
 src/common.h                                    |   10 
 src/i915_video.c                                |    1 
 src/i965_render.c                               |   31 
 src/i965_video.c                                |  599 +-
 src/intel.h                                     |   13 
 src/intel_batchbuffer.c                         |    2 
 src/intel_display.c                             |   27 
 src/intel_dri.c                                 |    3 
 src/intel_driver.c                              |   30 
 src/intel_driver.h                              |    3 
 src/intel_glamor.c                              |  228 
 src/intel_glamor.h                              |   68 
 src/intel_memory.c                              |   86 
 src/intel_module.c                              |   22 
 src/intel_uxa.c                                 |  148 
 src/intel_video.c                               |    1 
 src/render_program/Makefile.am                  |   78 
 src/render_program/exa_sf.g5a                   |   99 
 src/render_program/exa_sf.g5b                   |    7 
 src/render_program/exa_sf_mask.g5a              |   99 
 src/render_program/exa_sf_mask.g5b              |    7 
 src/render_program/exa_wm_ca.g5a                |   38 
 src/render_program/exa_wm_ca.g5b                |    4 
 src/render_program/exa_wm_ca_srcalpha.g5a       |   37 
 src/render_program/exa_wm_ca_srcalpha.g5b       |    4 
 src/render_program/exa_wm_mask_affine.g5a       |   31 
 src/render_program/exa_wm_mask_affine.g5b       |    4 
 src/render_program/exa_wm_mask_projective.g5a   |   53 
 src/render_program/exa_wm_mask_projective.g5b   |   16 
 src/render_program/exa_wm_mask_sample_a.g5a     |   49 
 src/render_program/exa_wm_mask_sample_a.g5b     |    3 
 src/render_program/exa_wm_mask_sample_argb.g5a  |   49 
 src/render_program/exa_wm_mask_sample_argb.g5b  |    3 
 src/render_program/exa_wm_noca.g5a              |   38 
 src/render_program/exa_wm_noca.g5b              |    4 
 src/render_program/exa_wm_src_affine.g5a        |   31 
 src/render_program/exa_wm_src_affine.g5b        |    4 
 src/render_program/exa_wm_src_projective.g5a    |   49 
 src/render_program/exa_wm_src_projective.g5b    |   16 
 src/render_program/exa_wm_src_sample_a.g5a      |   48 
 src/render_program/exa_wm_src_sample_a.g5b      |    3 
 src/render_program/exa_wm_src_sample_argb.g5a   |   46 
 src/render_program/exa_wm_src_sample_argb.g5b   |    2 
 src/render_program/exa_wm_src_sample_planar.g5a |   32 
 src/render_program/exa_wm_src_sample_planar.g5b |    5 
 src/render_program/exa_wm_write.g5a             |   55 
 src/render_program/exa_wm_write.g5b             |    6 
 src/render_program/exa_wm_xy.g5a                |   52 
 src/render_program/exa_wm_xy.g5b                |    4 
 src/render_program/exa_wm_yuv_rgb.g5a           |   98 
 src/render_program/exa_wm_yuv_rgb.g5b           |   12 
 src/sna/Makefile.am                             |    5 
 src/sna/blt.c                                   |   57 
 src/sna/compiler.h                              |   14 
 src/sna/gen2_render.c                           |  364 +
 src/sna/gen3_render.c                           |  671 +-
 src/sna/gen4_render.c                           |  297 -
 src/sna/gen5_render.c                           |  846 ++-
 src/sna/gen6_render.c                           |  686 ++
 src/sna/gen7_render.c                           |  757 ++-
 src/sna/gen7_render.h                           |  280 -
 src/sna/kgem.c                                  | 1708 +++++--
 src/sna/kgem.h                                  |  106 
 src/sna/kgem_debug.c                            |   10 
 src/sna/kgem_debug.h                            |    3 
 src/sna/kgem_debug_gen3.c                       |    4 
 src/sna/kgem_debug_gen4.c                       |    8 
 src/sna/kgem_debug_gen5.c                       |    8 
 src/sna/kgem_debug_gen6.c                       |   10 
 src/sna/kgem_debug_gen7.c                       |  747 +++
 src/sna/rop.h                                   |  264 +
 src/sna/sna.h                                   |  172 
 src/sna/sna_accel.c                             | 5755 +++++++++++++++++++-----
 src/sna/sna_blt.c                               |  321 -
 src/sna/sna_composite.c                         |  215 
 src/sna/sna_damage.c                            |  548 +-
 src/sna/sna_damage.h                            |   44 
 src/sna/sna_display.c                           |   87 
 src/sna/sna_dri.c                               |  981 ++--
 src/sna/sna_driver.c                            |  119 
 src/sna/sna_glyphs.c                            |  395 +
 src/sna/sna_gradient.c                          |   10 
 src/sna/sna_io.c                                |   96 
 src/sna/sna_reg.h                               |   46 
 src/sna/sna_render.c                            |  321 +
 src/sna/sna_render.h                            |   33 
 src/sna/sna_render_inline.h                     |   58 
 src/sna/sna_tiling.c                            |   38 
 src/sna/sna_trapezoids.c                        |  682 ++
 src/sna/sna_video.c                             |  255 -
 src/sna/sna_video.h                             |   25 
 src/sna/sna_video_overlay.c                     |   36 
 src/sna/sna_video_textured.c                    |   75 
 test/.gitignore                                 |    1 
 test/Makefile.am                                |    1 
 test/basic-copyarea-size.c                      |    6 
 test/basic-copyarea.c                           |    3 
 test/basic-fillrect.c                           |    3 
 test/basic-lines.c                              |  147 
 test/basic-putimage.c                           |    3 
 test/basic-stress.c                             |    3 
 test/mixed-stress.c                             |    3 
 test/render-composite-solid.c                   |    3 
 test/render-copyarea-size.c                     |    6 
 test/render-copyarea.c                          |    3 
 test/render-fill-copy.c                         |    3 
 test/render-fill.c                              |    3 
 test/render-trapezoid-image.c                   |    6 
 test/render-trapezoid.c                         |    6 
 test/test.h                                     |    2 
 test/test_image.c                               |    7 
 uxa/Makefile.am                                 |    6 
 uxa/uxa-accel.c                                 |  179 
 uxa/uxa-glamor.h                                |   56 
 uxa/uxa-glyphs.c                                |   40 
 uxa/uxa-priv.h                                  |   15 
 uxa/uxa-render.c                                |  242 -
 uxa/uxa-unaccel.c                               |   92 
 uxa/uxa.c                                       |   41 
 uxa/uxa.h                                       |   13 
 124 files changed, 15666 insertions(+), 4854 deletions(-)

New commits:
commit 770a953ff03bb8328c3f29e274d225528840f30c
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 31 17:19:08 2011 +0000

    uxa/video: Clear all state structures before uploading
    
    A regression from eb859f644633e left some of the state uninitialised
    before uploading to the GPU leading to undefined behaviour.
    
    Reported-by: Alexey Shumitsky <alexey.shumitsky@gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44338
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44252
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/i965_video.c b/src/i965_video.c
index d14fb66..c94f530 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -588,6 +588,7 @@ static drm_intel_bo *gen7_create_sampler_state(ScrnInfoPtr scrn)
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	struct gen7_sampler_state sampler_state;
 
+	memset(&sampler_state, 0, sizeof(sampler_state));
 	sampler_state.ss0.min_filter = BRW_MAPFILTER_LINEAR;
 	sampler_state.ss0.mag_filter = BRW_MAPFILTER_LINEAR;
 	sampler_state.ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
@@ -605,6 +606,7 @@ static drm_intel_bo *i965_create_vs_state(ScrnInfoPtr scrn)
 	struct brw_vs_unit_state vs_state;
 
 	/* Set up the vertex shader to be disabled (passthrough) */
+	memset(&vs_state, 0, sizeof(vs_state));
 	if (IS_GEN5(intel))
 		vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES >> 2;
 	else
@@ -794,6 +796,7 @@ static drm_intel_bo *i965_create_cc_vp_state(ScrnInfoPtr scrn)
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	struct brw_cc_viewport cc_viewport;
 
+	memset(&cc_viewport, 0, sizeof(cc_viewport));
 	cc_viewport.min_depth = -1.e35;
 	cc_viewport.max_depth = 1.e35;
 
@@ -1360,6 +1363,7 @@ gen6_create_cc_state(ScrnInfoPtr scrn)
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	struct gen6_color_calc_state cc_state;
 
+	memset(&cc_state, 0, sizeof(cc_state));
 	cc_state.constant_r = 1.0;
 	cc_state.constant_g = 0.0;
 	cc_state.constant_b = 1.0;
@@ -1376,6 +1380,7 @@ gen6_create_blend_state(ScrnInfoPtr scrn)
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	struct gen6_blend_state blend_state;
 
+	memset(&blend_state, 0, sizeof(blend_state));
 	blend_state.blend1.logic_op_enable = 1;
 	blend_state.blend1.logic_op_func = 0xc;
 	blend_state.blend1.pre_blend_clamp_enable = 1;

commit f1995c684d2e074ae04c9e42727e59cc77e16104
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 31 15:57:32 2011 +0000

    uxa: the video destination should be in the render write domain
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/i965_video.c b/src/i965_video.c
index a130f3d..d14fb66 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -413,7 +413,7 @@ static void i965_create_dst_surface_state(ScrnInfoPtr scrn,
 
 	dest_surf_state.ss1.base_addr =
 	    intel_emit_reloc(surf_bo, offset + offsetof(struct brw_surface_state, ss1),
-			     pixmap_bo, 0, I915_GEM_DOMAIN_SAMPLER, 0);
+			     pixmap_bo, 0, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
 
 	dest_surf_state.ss2.height = pixmap->drawable.height - 1;
 	dest_surf_state.ss2.width = pixmap->drawable.width - 1;

commit 511146d2e40e267f74e18c0dd06b65f5d6a69f5d
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 31 13:27:13 2011 +0000

    sna: Implement inplace trapezoidal addition (for clipmasks)
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 9222f2f..f7fbdb2 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -3138,6 +3138,80 @@ tor_blt_in_clipped_mono(struct sna *sna,
 			   coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY);
 }
 
+static void
+tor_blt_add(struct sna *sna,
+	    struct sna_composite_spans_op *op,
+	    pixman_region16_t *clip,
+	    const BoxRec *box,
+	    int coverage)
+{
+	struct inplace *in = (struct inplace *)op;
+	uint8_t *ptr = in->ptr;
+	int h, w, v, i;
+
+	coverage = coverage * in->opacity / FAST_SAMPLES_XY;
+	if (coverage == 0)
+		return;
+
+	ptr += box->y1 * in->stride + box->x1;
+
+	h = box->y2 - box->y1;
+	w = box->x2 - box->x1;
+	if ((w | h) == 1) {
+		v = coverage + *ptr;
+		*ptr = v >= 255 ? 255 : v;
+	} else {
+		do {
+			for (i = 0; i < w; i++) {
+				v = coverage + ptr[i];
+				ptr[i] = v >= 255 ? 255 : v;
+			}
+			ptr += in->stride;
+		} while (--h);
+	}
+}
+
+static void
+tor_blt_add_clipped(struct sna *sna,
+		    struct sna_composite_spans_op *op,
+		    pixman_region16_t *clip,
+		    const BoxRec *box,
+		    int coverage)
+{
+	pixman_region16_t region;
+	int n;
+
+	pixman_region_init_rects(&region, box, 1);
+	RegionIntersect(&region, &region, clip);
+	n = REGION_NUM_RECTS(&region);
+	box = REGION_RECTS(&region);
+	while (n--)
+		tor_blt_add(sna, op, NULL, box++, coverage);
+	pixman_region_fini(&region);
+}
+
+static void
+tor_blt_add_mono(struct sna *sna,
+		 struct sna_composite_spans_op *op,
+		 pixman_region16_t *clip,
+		 const BoxRec *box,
+		 int coverage)
+{
+	if (coverage >= FAST_SAMPLES_XY/2)
+		tor_blt_add(sna, op, clip, box, FAST_SAMPLES_XY);
+}
+
+static void
+tor_blt_add_clipped_mono(struct sna *sna,
+			 struct sna_composite_spans_op *op,
+			 pixman_region16_t *clip,
+			 const BoxRec *box,
+			 int coverage)
+{
+	if (coverage >= FAST_SAMPLES_XY/2)
+		tor_blt_add_clipped(sna, op, clip, box, FAST_SAMPLES_XY);
+}
+
 static bool
 trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst,
 		       PictFormatPtr maskFormat, INT16 src_x, INT16 src_y,
@@ -3167,17 +3241,26 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst,
 		return false;
 	}
 
-	DBG(("%s: format=%x, op=%d, color=%x\n",
-	     __FUNCTION__, dst->format, op, color));
+	if (dst->format != PICT_a8 || !sna_picture_is_solid(src, &color)) {
+		DBG(("%s: fallback -- can not perform operation in place, format=%x\n",
+		     __FUNCTION__, dst->format));
+		return false;
+	}
 
-	if (dst->format != PICT_a8 ||
-	    !(op == PictOpSrc || op == PictOpIn) ||
-	    !sna_picture_is_solid(src, &color)) {
-		DBG(("%s: fallback -- can not perform operation in place\n",
-		     __FUNCTION__));
+	switch (op) {
+	case PictOpSrc:
+	case PictOpIn:
+	case PictOpAdd:
+		break;
+	default:
+		DBG(("%s: fallback -- can not perform op [%d] in place\n",
+		     __FUNCTION__, op));
 		return false;
 	}
 
+	DBG(("%s: format=%x, op=%d, color=%x\n",
+	     __FUNCTION__, dst->format, op, color));
+
 	if (maskFormat == NULL && ntrap > 1) {
 		DBG(("%s: individual rasterisation requested\n",
 		     __FUNCTION__));
@@ -3246,7 +3329,7 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst,
 			else
 				span = tor_blt_src;
 		}
-	} else {
+	} else if (op == PictOpIn) {
 		if (dst->pCompositeClip->data) {
 			if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp)
 				span = tor_blt_in_clipped_mono;
@@ -3258,6 +3341,18 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst,
 			else
 				span = tor_blt_in;
 		}
+	} else {
+		if (dst->pCompositeClip->data) {
+			if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp)
+				span = tor_blt_add_clipped_mono;
+			else
+				span = tor_blt_add_clipped;
+		} else {
+			if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp)
+				span = tor_blt_add_mono;
+			else
+				span = tor_blt_add;
+		}
 	}
 
 	region.data = NULL;

commit a1f585a3d0ae72e896684f62960a9ae96dc259f5
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 31 12:43:04 2011 +0000

    sna: Update pixmap->devKind for GTT mappings
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 37b904c..feba5b5 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -139,6 +139,8 @@ struct sna_pixmap {
 	struct list list;
 	struct list inactive;
 
+	uint32_t stride;
+
 #define SOURCE_BIAS 4
 	uint16_t source_count;
 	uint8_t pinned :1;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c72d9e6..94b051e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -193,7 +193,7 @@ sna_pixmap_alloc_cpu(struct sna *sna,
 	if (priv->ptr)
 		goto done;
 
-	assert(pixmap->devKind);
+	assert(priv->stride);
 
 	if (!DEBUG_NO_LLC && sna->kgem.gen >= 60) {
 		DBG(("%s: allocating CPU buffer (%dx%d)\n", __FUNCTION__,
@@ -213,16 +213,18 @@ sna_pixmap_alloc_cpu(struct sna *sna,
 			if (priv->ptr == NULL) {
 				kgem_bo_destroy(&sna->kgem, priv->cpu_bo);
 				priv->cpu_bo = NULL;
-			}
+			} else
+				priv->stride = priv->cpu_bo->pitch;
 		}
 	}
 
 	if (priv->ptr == NULL)
-		priv->ptr = malloc(pixmap->devKind * pixmap->drawable.height);
+		priv->ptr = malloc(priv->stride * pixmap->drawable.height);
 
 	assert(priv->ptr);
 done:
 	pixmap->devPrivate.ptr = priv->ptr;
+	pixmap->devKind = priv->stride;
 	return priv->ptr != NULL;
 }
 
@@ -272,9 +274,6 @@ static Bool sna_destroy_private(PixmapPtr pixmap, struct sna_pixmap *priv)
 	if (!sna->freed_pixmap && priv->header) {
 		sna->freed_pixmap = pixmap;
 		assert(priv->ptr == NULL);
-		priv->gpu_bo = NULL;
-		priv->cpu_bo = NULL;
-		priv->mapped = 0;
 		return false;
 	}
 
@@ -535,7 +534,7 @@ sna_pixmap_create_scratch(ScreenPtr screen,
 		}
 	}
 
-	pixmap->devKind = PixmapBytePad(width, depth);
+	priv->stride = PixmapBytePad(width, depth);
 	pixmap->devPrivate.ptr = NULL;
 
 	priv->gpu_bo = kgem_create_2d(&sna->kgem,
@@ -550,7 +549,6 @@ sna_pixmap_create_scratch(ScreenPtr screen,
 	priv->header = true;
 	sna_damage_all(&priv->gpu_damage, width, height);
 
-
 	return pixmap;
 }
 
@@ -601,6 +599,7 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 		sna_pixmap_attach(pixmap);
 	} else {
 		struct sna *sna = to_sna_from_screen(screen);
+		struct sna_pixmap *priv;
 
 		pixmap = create_pixmap(sna, screen, 0, 0, depth, usage);
 		if (pixmap == NullPixmap)
@@ -611,12 +610,15 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 		pixmap->devKind = pad;
 		pixmap->devPrivate.ptr = NULL;
 
-		if (sna_pixmap_attach(pixmap) == NULL) {
+		priv = sna_pixmap_attach(pixmap);
+		if (priv == NULL) {
 			free(pixmap);
 			return create_pixmap(sna, screen,
 					     width, height, depth,
 					     usage);
 		}
+
+		priv->stride = pad;
 	}
 
 	return pixmap;
@@ -678,7 +680,8 @@ sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 		sna_damage_destroy(&priv->cpu_damage);
 		sna_damage_destroy(&priv->gpu_damage);
 
-		if (priv->gpu_bo && pixmap_inplace(sna, pixmap, priv)) {
+		if (priv->stride && priv->gpu_bo &&
+		    pixmap_inplace(sna, pixmap, priv)) {
 			if (kgem_bo_is_busy(priv->gpu_bo) &&
 			    priv->gpu_bo->exec == NULL)
 				kgem_retire(&sna->kgem);
@@ -696,6 +699,7 @@ sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 				goto skip_inplace_map;
 
 			priv->mapped = 1;
+			pixmap->devKind = priv->gpu_bo->pitch;
 
 			sna_damage_all(&priv->gpu_damage,
 				       pixmap->drawable.width,
@@ -895,7 +899,8 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	if ((flags & MOVE_READ) == 0) {
 		assert(flags == MOVE_WRITE);
 
-		if (priv->gpu_bo && region_inplace(sna, pixmap, region, priv)) {
+		if (priv->stride && priv->gpu_bo &&
+		    region_inplace(sna, pixmap, region, priv)) {
 			if (sync_will_stall(priv->gpu_bo) &&
 			    priv->gpu_bo->exec == NULL)
 				kgem_retire(&sna->kgem);
@@ -908,6 +913,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 					return false;
 
 				priv->mapped = 1;
+				pixmap->devKind = priv->gpu_bo->pitch;
 
 				sna_damage_subtract(&priv->cpu_damage, region);
 				if (priv->cpu_damage == NULL)
@@ -945,6 +951,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 				return false;
 
 			priv->mapped = 1;
+			pixmap->devKind = priv->gpu_bo->pitch;
 
 			sna_damage_subtract(&priv->cpu_damage, region);
 			if (priv->cpu_damage == NULL)

commit 343de19ef98eea016601dbbe2d1f601dbff9de20
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 31 11:19:44 2011 +0000

    sna: Implement tiled uploads for small stipples larger than patterns
    
    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 fd67143..c72d9e6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -7425,6 +7425,215 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 	return true;
 }
 
+static void
+sna_poly_fill_rect_stippled_n_box(struct sna *sna,
+				  struct kgem_bo *bo,
+				  uint32_t br00, uint32_t br13,
+				  GCPtr gc,
+				  BoxRec *box,
+				  DDXPointRec *origin)
+{
+	int x1, x2, y1, y2;
+	uint32_t *b;
+
+	for (y1 = box->y1; y1 < box->y2; y1 = y2) {
+		int oy = (y1 - origin->y)  % gc->stipple->drawable.height;
+
+		y2 = box->y2;
+		if (y2 - y1 > gc->stipple->drawable.height - oy)
+			y2 = y1 + gc->stipple->drawable.height - oy;
+
+		for (x1 = box->x1; x1 < box->x2; x1 = x2) {
+			int bx1, bx2, bw, bh, len, ox;
+			uint8_t *dst, *src;
+
+			x2 = box->x2;
+			ox = (x1 - origin->x) % gc->stipple->drawable.width;
+			bx1 = ox & ~7;
+			bx2 = ox + (x2 - x1);
+			if (bx2 - bx1 > gc->stipple->drawable.width) {
+				bx2 = bx1 + gc->stipple->drawable.width;
+				x2 = x1 + (bx2 - bx1);
+			}
+			bx2 = (bx2 + 7) &~7;
+			bw = (bx2 - bx1)/8;
+			bw = ALIGN(bw, 2);
+			bh = y2 - y1;
+
+			DBG(("%s: box(%d, %d), (%d, %d) pat=(%d, %d)\n",
+			     __FUNCTION__, x1, y1, x2, y2, ox, oy));
+
+			len = bw*bh;
+			len = ALIGN(len, 8) / 4;
+			if (!kgem_check_batch(&sna->kgem, 7+len) ||
+			    !kgem_check_bo_fenced(&sna->kgem, bo, NULL) ||
+			    !kgem_check_reloc(&sna->kgem, 1)) {
+				_kgem_submit(&sna->kgem);
+				_kgem_set_mode(&sna->kgem, KGEM_BLT);
+			}
+
+			b = sna->kgem.batch + sna->kgem.nbatch;
+			b[0] = XY_MONO_SRC_COPY_IMM | (5 + len) | br00;
+			b[0] |= (ox & 7) << 17;
+			b[1] = br13;
+			b[2] = y1 << 16 | x1;
+			b[3] = y2 << 16 | x2;
+			b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4,
+					      bo,
+					      I915_GEM_DOMAIN_RENDER << 16 |
+					      I915_GEM_DOMAIN_RENDER |
+					      KGEM_RELOC_FENCED,
+					      0);
+			b[5] = gc->bgPixel;
+			b[6] = gc->fgPixel;
+
+			sna->kgem.nbatch += 7 + len;
+
+			dst = (uint8_t *)&b[7];
+			len = gc->stipple->devKind;
+			src = gc->stipple->devPrivate.ptr;
+			src += oy*len + ox/8;
+			len -= bw;
+			do {
+				int i = bw;
+				do {
+					*dst++ = byte_reverse(*src++);
+					*dst++ = byte_reverse(*src++);
+					i -= 2;
+				} while (i);
+				src += len;
+			} while (--bh);
+		}
+	}
+}
+
+static bool
+sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
+				  struct kgem_bo *bo,
+				  struct sna_damage **damage,
+				  GCPtr gc, int n, xRectangle *r,
+				  const BoxRec *extents, unsigned clipped)
+{
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
+	DDXPointRec origin = gc->patOrg;
+	int16_t dx, dy;
+	uint32_t br00, br13;
+
+	DBG(("%s: upload (%d, %d), (%d, %d), origin (%d, %d)\n", __FUNCTION__,
+	     extents->x1, extents->y1,
+	     extents->x2, extents->y2,
+	     origin.x, origin.y));
+
+	if (gc->stipple->drawable.width > 32 ||
+	    gc->stipple->drawable.height > 32)
+		return false;
+
+	get_drawable_deltas(drawable, pixmap, &dx, &dy);
+	kgem_set_mode(&sna->kgem, KGEM_BLT);
+
+	br00 = 3 << 20;
+	br13 = bo->pitch;
+	if (sna->kgem.gen >= 40) {
+		if (bo->tiling)
+			br00 |= BLT_DST_TILED;
+		br13 >>= 2;
+	}
+	br13 |= (gc->fillStyle == FillStippled) << 29;
+	br13 |= blt_depth(drawable->depth) << 24;
+	br13 |= copy_ROP[gc->alu] << 16;
+
+	origin.x += dx + drawable->x;
+	origin.y += dy + drawable->y;
+
+	if (!clipped) {
+		dx += drawable->x;
+		dy += drawable->y;
+
+		sna_damage_add_rectangles(damage, r, n, dx, dy);
+		do {
+			BoxRec box;
+
+			box.x1 = r->x + dx;
+			box.y1 = r->y + dy;
+			box.x2 = box.x1 + r->width;
+			box.y2 = box.y1 + r->height;
+
+			sna_poly_fill_rect_stippled_n_box(sna, bo,
+							  br00, br13, gc,
+							  &box, &origin);
+			r++;
+		} while (--n);
+	} else {
+		RegionRec clip;
+
+		region_set(&clip, extents);
+		region_maybe_clip(&clip, gc->pCompositeClip);
+		if (!RegionNotEmpty(&clip))
+			return true;
+
+		if (clip.data == NULL) {
+			do {
+				BoxRec box;
+
+				box.x1 = r->x + drawable->x;
+				box.x2 = bound(r->x, r->width);
+				box.y1 = r->y + drawable->y;
+				box.y2 = bound(r->y, r->height);
+				r++;
+
+				if (!box_intersect(&box, &clip.extents))
+					continue;
+
+				box.x1 += dx; box.x2 += dx;
+				box.y1 += dy; box.y2 += dy;
+
+				sna_poly_fill_rect_stippled_n_box(sna, bo,
+								  br00, br13, gc,
+								  &box, &origin);
+			} while (--n);
+		} else {
+			const BoxRec * const clip_start = RegionBoxptr(&clip);
+			const BoxRec * const clip_end = clip_start + clip.data->numRects;
+			const BoxRec *c;
+
+			do {
+				BoxRec unclipped;
+
+				unclipped.x1 = r->x + drawable->x;
+				unclipped.x2 = bound(r->x, r->width);
+				unclipped.y1 = r->y + drawable->y;
+				unclipped.y2 = bound(r->y, r->height);
+				r++;
+
+				c = find_clip_box_for_y(clip_start,
+							clip_end,
+							unclipped.y1);
+				while (c != clip_end) {
+					BoxRec box;
+
+					if (unclipped.y2 <= c->y1)
+						break;
+
+					box = unclipped;
+					if (!box_intersect(&box, c++))
+						continue;
+
+					box.x1 += dx; box.x2 += dx;
+					box.y1 += dy; box.y2 += dy;
+
+					sna_poly_fill_rect_stippled_n_box(sna, bo,
+									  br00, br13, gc,
+									  &box, &origin);
+				}
+			} while (--n);
+		}
+	}
+
+	sna->blt_state.fill_bo = 0;
+	return true;
+}
+
 static bool
 sna_poly_fill_rect_stippled_blt(DrawablePtr drawable,
 				struct kgem_bo *bo,
@@ -7470,9 +7679,11 @@ sna_poly_fill_rect_stippled_blt(DrawablePtr drawable,
 			return sna_poly_fill_rect_stippled_1_blt(drawable, bo, damage,
 								 gc, n, rect,
 								 extents, clipped);
+	} else {
+		return sna_poly_fill_rect_stippled_n_blt(drawable, bo, damage,
+							 gc, n, rect,
+							 extents, clipped);
 	}
-
-	return false;
 }
 
 static unsigned

commit fb15cf2294da20bfc375ae62443b822770850316
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 31 10:24:58 2011 +0000

    sna: Make sure the shadow pixmap is suitable for scanout
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index a751354..8e141c6 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -749,7 +749,9 @@ sna_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 
 	DBG(("%s(%d, %d)\n", __FUNCTION__, width, height));
 
-	shadow = scrn->pScreen->CreatePixmap(scrn->pScreen, width, height, scrn->depth, 0);
+	shadow = scrn->pScreen->CreatePixmap(scrn->pScreen,
+					     width, height, scrn->depth,
+					     SNA_CREATE_FB);
 	if (!shadow)
 		return NULL;
 

commit 281425551bdab7eb38ae167a3205b14ae3599c49
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Sat Dec 31 10:10:00 2011 +0000

    sna: Tweak throttling to be run before going idle
    
    The goal is to avoid introducing extra latency in the middle of a
    command sequence and to delay it until we have to wait for the clients.
    
    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 85bddd0..fd67143 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -9182,7 +9182,7 @@ static bool sna_accel_flush(struct sna *sna)
 	sna->kgem.busy = !nothing_to_do;
 	kgem_bo_flush(&sna->kgem, priv->gpu_bo);
 	sna->kgem.flush_now = 0;
-	return need_throttle;
+	return need_throttle && !sna->kgem.busy;
 }
 
 static void sna_accel_expire(struct sna *sna)
@@ -9463,9 +9463,6 @@ static void sna_accel_throttle(struct sna *sna)
 	if (sna->flags & SNA_NO_THROTTLE)
 		return;
 
-	if (list_is_empty(&sna->kgem.requests))
-		return;
-
 	DBG(("%s (time=%ld)\n", __FUNCTION__, (long)GetTimeInMillis()));
 
 	kgem_throttle(&sna->kgem);

commit 2f5448f1329f344702e4e29b2509d7190677bbf0
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Dec 30 22:13:05 2011 +0000

    sna: compare tiling against minimum width for relevancy
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 45aa5f8..89b464e 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1788,7 +1788,7 @@ int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int
 		tiling = I915_TILING_NONE;
 		goto done;
 	}
-	if (tiling == I915_TILING_Y && width * bpp <= 8*32/2) {
+	if (tiling == I915_TILING_Y && width * bpp <= 8*128/2) {
 		DBG(("%s: too thin [%d] for TILING_Y\n",
 		     __FUNCTION__, width));
 		tiling = I915_TILING_NONE;

commit e82b3d8069629ae5776e039d6ea1f3c901a3a094
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Dec 30 09:16:00 2011 +0000

    sna: Defer the initial source upload if the GPU bo will be untiled
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index e7c3df4..aa9c160 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -317,7 +317,12 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
 	if (w == pixmap->drawable.width && h == pixmap->drawable.height) {
 		bool upload = true;
 
-		if (pixmap->devKind * pixmap->drawable.height <= 4096) {
+		if (pixmap->devKind * pixmap->drawable.height <= 4096 ||
+		    kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem,
+				       I915_TILING_X,
+				       pixmap->drawable.width,
+				       pixmap->drawable.height,
+				       pixmap->drawable.bitsPerPixel) == I915_TILING_NONE) {
 			priv = sna_pixmap(pixmap);
 			upload = priv && priv->source_count++ > SOURCE_BIAS;
 		}
@@ -339,6 +344,12 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
 	if (priv)
 		count = priv->source_count++;
 
+	if (kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem, I915_TILING_X,
+			       pixmap->drawable.width,
+			       pixmap->drawable.height,
+			       pixmap->drawable.bitsPerPixel) == I915_TILING_NONE)
+		count -= SOURCE_BIAS;
+
 	DBG(("%s: migrate box (%d, %d), (%d, %d)? source count=%d, fraction=%d/%d [%d]\n",
 	     __FUNCTION__,
 	     box->x1, box->y1, box->x2, box->y2,

commit 72624b0b5ba6549cb8d96f992d2656a28ec6078c
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Dec 29 22:43:35 2011 +0000

    sna: Remove redundant use-gpu-bo clause
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 79aa08f..37b904c 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -144,7 +144,6 @@ struct sna_pixmap {
 	uint8_t pinned :1;
 	uint8_t mapped :1;
 	uint8_t flush :1;
-	uint8_t gpu :1;
 	uint8_t header :1;
 };
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ee8d7ea..85bddd0 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -704,7 +704,6 @@ sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 			if (priv->cpu_bo)
 				sna_pixmap_free_cpu(sna, priv);
 
-			priv->gpu = true;
 			return true;
 		}
 
@@ -784,7 +783,6 @@ done:
 	}
 
 	priv->source_count = SOURCE_BIAS;
-	priv->gpu = false;
 	return true;
 }
 
@@ -920,7 +918,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 					sna_damage_add(&priv->gpu_damage,
 						       region);
 
-				priv->gpu = true;
 				return true;
 			}
 		}
@@ -957,7 +954,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 			else
 				sna_damage_add(&priv->gpu_damage, region);
 
-			priv->gpu = true;
 			return true;
 		}
 	}
@@ -1082,7 +1078,6 @@ done:
 		RegionTranslate(region, -dx, -dy);
 
 	priv->source_count = SOURCE_BIAS;
-	priv->gpu = false;
 	return true;
 }
 
@@ -1167,7 +1162,6 @@ done:
 		list_del(&priv->list);
 	if (!priv->pinned)
 		list_move(&priv->inactive, &sna->active_pixmaps);
-	priv->gpu = true;
 	return true;
 }
 
@@ -1191,14 +1185,10 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 	if (priv == NULL)
 		return FALSE;
 
-	if (priv->cpu_damage == NULL &&
-	    sna_pixmap_choose_tiling(pixmap) != I915_TILING_NONE &&
-	    !sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE))
-		return FALSE;
-
 	if (priv->gpu_bo == NULL &&
 	    (sna_pixmap_choose_tiling(pixmap) == I915_TILING_NONE ||
-	     !box_inplace(pixmap, box)))
+	     (priv->cpu_damage && !box_inplace(pixmap, box)) ||
+	     !sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE | MOVE_READ)))
 		return FALSE;
 
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
@@ -1209,37 +1199,47 @@ _sna_drawable_use_gpu_bo(DrawablePtr drawable,
 	extents.y1 += dy;
 	extents.y2 += dy;
 
-	if (priv->gpu) {
-		if (priv->gpu_damage &&
-		    sna_damage_contains_box(priv->gpu_damage,
-					    &extents) != PIXMAN_REGION_OUT)
+	if (priv->gpu_damage) {
+		int ret = sna_damage_contains_box(priv->gpu_damage, &extents);
+		if (ret == PIXMAN_REGION_IN) {
+			DBG(("%s: region wholly contained within GPU damage\n",
+			     __FUNCTION__));
+			*damage = NULL;
+			return TRUE;
+		}
+
+		if (ret != PIXMAN_REGION_OUT && kgem_bo_is_busy(priv->gpu_bo)) {
+			DBG(("%s: region partially contained within busy GPU damage\n",
+			     __FUNCTION__));
 			goto move_to_gpu;
+		}
+	}
 
-		if (priv->cpu_damage &&
-		    sna_damage_contains_box(priv->cpu_damage,
-					    &extents) != PIXMAN_REGION_OUT)
+	if (priv->cpu_damage) {
+		int ret = sna_damage_contains_box(priv->cpu_damage, &extents);
+		if (ret == PIXMAN_REGION_IN) {
+			DBG(("%s: region wholly contained within CPU damage\n",


Reply to: