xf86-video-intel: 7 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_composite.c src/sna/sna.h src/sna/sna_render.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Jan 22 08:09:37 PST 2012


 src/sna/kgem.c          |    2 
 src/sna/sna.h           |    2 
 src/sna/sna_accel.c     |  158 +++++++++++++++++++++++++++++++++++++++++++-----
 src/sna/sna_composite.c |   13 +++
 src/sna/sna_render.c    |   42 ++++++++----
 5 files changed, 186 insertions(+), 31 deletions(-)

New commits:
commit 5aa494305e90eed5df211427741a75380add8e96
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 22 16:10:39 2012 +0000

    sna: Correct the offsets for performing partial downsampling on the GPU
    
    Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=45086
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 0796453..5f79e04 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -785,7 +785,7 @@ static int sna_render_picture_downsample(struct sna *sna,
 				if (!sna->render.composite(sna,
 							   PictOpSrc,
 							   tmp_src, NULL, tmp_dst,
-							   box.x1 + b.x1, box.y1 + b.y1,
+							   box.x1/2 + b.x1, box.y1/2 + b.y1,
 							   0, 0,
 							   b.x1, b.y1,
 							   b.x2 - b.x1, b.y2 - b.y1,
commit a7b24bb4342eefb2b23fa40d7c7216c38f2edc09
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 22 15:50:47 2012 +0000

    sna: Correct image buffer size when uploading a downsampled image
    
    Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=45086
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 3b4db90..8b553b9 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3224,7 +3224,7 @@ struct kgem_bo *kgem_upload_source_image_halved(struct kgem *kgem,
 	     __FUNCTION__, x, y, width, height, stride, bpp));
 
 	bo = kgem_create_buffer_2d(kgem,
-				   width, height, bpp,
+				   width/2, height/2, bpp,
 				   KGEM_BUFFER_WRITE_INPLACE,
 				   &dst);
 	if (bo == NULL)
commit 238fc67aa945d5669eccd2a8fe8e98402b9a6223
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 22 16:04:13 2012 +0000

    sna: Incude prefer-gpu hint in decision to upload CPU textures
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index efe415e..0796453 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -373,17 +373,20 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
 	w = box->x2 - box->x1;
 	h = box->y2 - box->y1;
 	if (w == pixmap->drawable.width && h == pixmap->drawable.height) {
-		bool upload = true;
+		bool upload;
 
-		if (pixmap->devKind * pixmap->drawable.height <= 4096 ||
+		priv = sna_pixmap_attach(pixmap);
+		if (!priv)
+			return false;
+
+		upload = true;
+		if (!priv->gpu ||
 		    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_attach(pixmap);
-			upload = priv && priv->source_count++ > SOURCE_BIAS;
-		}
+				       pixmap->drawable.bitsPerPixel) == I915_TILING_NONE)
+			upload = priv->source_count++ > SOURCE_BIAS;
 
 		DBG(("%s: migrating whole pixmap (%dx%d) for source (%d,%d),(%d,%d)? %d\n",
 		     __FUNCTION__,
@@ -397,12 +400,14 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box)
 	if (64*w*h < pixmap->drawable.width * pixmap->drawable.height)
 		return FALSE;
 
-	count = SOURCE_BIAS;
 	priv = sna_pixmap_attach(pixmap);
-	if (priv)
-		count = priv->source_count++;
+	if (!priv)
+		return FALSE;
 
-	if (kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem, I915_TILING_X,
+	count = priv->source_count++;
+	if (!priv->gpu ||
+	    kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem,
+			       I915_TILING_X,
 			       pixmap->drawable.width,
 			       pixmap->drawable.height,
 			       pixmap->drawable.bitsPerPixel) == I915_TILING_NONE)
commit aeaffb102190a8846c6341e72a4338b41639d679
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 22 15:52:41 2012 +0000

    sna: Add some more DBG along the downsampling source extraction path
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index fde95f9..efe415e 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -671,11 +671,17 @@ static int sna_render_picture_downsample(struct sna *sna,
 
 	w = box.x2 - box.x1;
 	h = box.y2 - box.y1;
+	DBG(("%s: sample area (%d, %d), (%d, %d): %dx%d\n",
+	     __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h));
 	assert(w && h);
-	if (w > 2*sna->render.max_3d_size || h > 2*sna->render.max_3d_size)
+	if (w > 2*sna->render.max_3d_size || h > 2*sna->render.max_3d_size) {
+		DBG(("%s: sample size too large for pixman downscaling\n",
+		     __FUNCTION__));
 		goto fixup;
+	}
 
 	if (texture_is_cpu(pixmap, &box) && !move_to_gpu(pixmap, &box)) {
+		DBG(("%s: uploading partial texture\n", __FUNCTION__));
 		bo = kgem_upload_source_image_halved(&sna->kgem,
 						     picture->format,
 						     pixmap->devPrivate.ptr,
@@ -746,8 +752,8 @@ static int sna_render_picture_downsample(struct sna *sna,
 			ni = 1;
 		}
 
-		DBG(("%s downsampling using %dx%d GPU tiles\n",
-		     __FUNCTION__, ww, hh));
+		DBG(("%s %d:%d downsampling using %dx%d GPU tiles\n",
+		     __FUNCTION__, nj, ni, ww, hh));
 
 		for (i = 0; i < ni; i++) {
 			BoxRec b;
@@ -767,6 +773,9 @@ static int sna_render_picture_downsample(struct sna *sna,
 				else
 					b.x2 = b.x1 + ww;
 
+				DBG(("%s: tile %d:%d, box=(%d,%d), (%d, %d)\n",
+				     __FUNCTION__, i, j, b.x1, b.y1, b.x2, b.y2));
+
 				memset(&op, 0, sizeof(op));
 				if (!sna->render.composite(sna,
 							   PictOpSrc,
commit 92badc9c9c2636284af8bc56b098d24ff222f167
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 22 12:41:31 2012 +0000

    sna: Avoid a common readback after clearing
    
    It is surprisingly common for a pixmap to be created, cleared and then
    used as an upload target or, even worse, as a source for a ShmGetImage.
    In order to prevent this folly, we can trivially track when we clear an
    entire pixmap and its GPU bo and avoid the readback in such cases.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 0c0cb39..38ae404 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -137,12 +137,14 @@ struct sna_pixmap {
 	struct list inactive;
 
 	uint32_t stride;
+	uint32_t clear_color;
 
 #define SOURCE_BIAS 4
 	uint16_t source_count;
 	uint8_t pinned :1;
 	uint8_t mapped :1;
 	uint8_t flush :1;
+	uint8_t clear :1;
 	uint8_t undamaged :1;
 	uint8_t gpu :1;
 	uint8_t header :1;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 1e9ee16..f9b3a48 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -798,6 +798,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 	if ((flags & MOVE_READ) == 0) {
 		assert(flags & MOVE_WRITE);
 		sna_damage_destroy(&priv->gpu_damage);
+		priv->clear = false;
 
 		if (priv->gpu && pixmap_inplace(sna, pixmap, priv)) {
 			DBG(("%s: write inplace\n", __FUNCTION__));
@@ -882,6 +883,7 @@ skip_inplace_map:
 			sna_damage_all(&priv->gpu_damage,
 				       pixmap->drawable.width,
 				       pixmap->drawable.height);
+			priv->clear = false;
 			return true;
 		}
 
@@ -897,6 +899,28 @@ skip_inplace_map:
 	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL))
 		return false;
 
+	if (priv->clear) {
+		DBG(("%s: applying clear [%08x]\n",
+		     __FUNCTION__, priv->clear_color));
+
+		if (priv->cpu_bo) {
+			DBG(("%s: syncing CPU bo\n", __FUNCTION__));
+			kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
+		}
+
+		pixman_fill(pixmap->devPrivate.ptr,
+			    pixmap->devKind/sizeof(uint32_t),
+			    pixmap->drawable.bitsPerPixel,
+			    0, 0,
+			    pixmap->drawable.width,
+			    pixmap->drawable.height,
+			    priv->clear_color);
+
+		sna_damage_destroy(&priv->gpu_damage);
+		priv->undamaged = true;
+		priv->clear = false;
+	}
+
 	if (priv->gpu_damage) {
 		BoxPtr box;
 		int n;
@@ -1082,6 +1106,9 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	if (DAMAGE_IS_ALL(priv->cpu_damage))
 		goto out;
 
+	if (priv->clear)
+		return _sna_pixmap_move_to_cpu(pixmap, flags);
+
 	if (priv->gpu_bo == NULL && !priv->gpu && flags & MOVE_WRITE)
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 
@@ -1575,6 +1602,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
 done:
 	if (!priv->pinned)
 		list_move(&priv->inactive, &sna->active_pixmaps);
+	priv->clear = false;
 	return true;
 }
 
@@ -2008,6 +2036,7 @@ done:
 active:
 	if (!priv->pinned)
 		list_move(&priv->inactive, &sna->active_pixmaps);
+	priv->clear = false;
 	return priv;
 }
 
@@ -2341,6 +2370,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 			}
 		}
 
+		priv->clear = false;
 		return true;
 	}
 
@@ -2373,6 +2403,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 							sna_damage_add(&priv->gpu_damage, region);
 					}
 
+					priv->clear = false;
 					return true;
 				}
 			} else {
@@ -2436,6 +2467,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		}
 		if (priv->flush)
 			list_move(&priv->list, &sna->dirty_pixmaps);
+		priv->clear = false;
 	}
 
 blt:
@@ -2969,7 +3001,7 @@ fallback:
 				      alu, -1, bpp,
 				      reverse, upsidedown);
 				box++;
-			}while (--n);
+			} while (--n);
 		}
 	}
 }
@@ -3097,7 +3129,62 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			goto fallback;
 		}
 
-		if (src_priv &&
+		if (src_priv && src_priv->clear) {
+			DBG(("%s: applying src clear[%08x] to dst\n",
+			     __FUNCTION__, src_priv->clear_color));
+			RegionTranslate(&region, dst_dx, dst_dy);
+			if (n == 1) {
+				if (!sna->render.fill_one(sna,
+							  dst_pixmap,
+							  dst_priv->gpu_bo,
+							  src_priv->clear_color,
+							  box->x1, box->y1,
+							  box->x2, box->y2,
+							  alu)) {
+					DBG(("%s: unsupported fill\n",
+					     __FUNCTION__));
+					goto fallback;
+				}
+			} else {
+				struct sna_fill_op fill;
+
+				if (!sna_fill_init_blt(&fill, sna,
+						       dst_pixmap, dst_priv->gpu_bo,
+						       alu, src_priv->clear_color)) {
+					DBG(("%s: unsupported fill\n",
+					     __FUNCTION__));
+					goto fallback;
+				}
+
+				fill.boxes(sna, &fill, box, n);
+				fill.done(sna, &fill);
+			}
+
+			if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) {
+				if (replaces) {
+					sna_damage_destroy(&dst_priv->cpu_damage);
+					sna_damage_all(&dst_priv->gpu_damage,
+						       dst_pixmap->drawable.width,
+						       dst_pixmap->drawable.height);
+					list_del(&dst_priv->list);
+					dst_priv->undamaged = false;
+
+					dst_priv->clear = true;
+					dst_priv->clear_color = src_priv->clear_color;
+				} else {
+					assert_pixmap_contains_box(dst_pixmap,
+								   RegionExtents(&region));
+					sna_damage_add(&dst_priv->gpu_damage, &region);
+				}
+				RegionTranslate(&region, -dst_dx, -dst_dy);
+			}
+
+			if (replaces) {
+				DBG(("%s: mark dst as clear\n", __FUNCTION__));
+				dst_priv->clear = true;
+				dst_priv->clear_color = src_priv->clear_color;
+			}
+		} else if (src_priv &&
 		    move_to_gpu(src_pixmap, src_priv, &region.extents, alu) &&
 		    sna_pixmap_move_to_gpu(src_pixmap, MOVE_READ)) {
 			if (!sna->render.copy_boxes(sna, alu,
@@ -3261,11 +3348,43 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				}
 			}
 		}
+
+		goto out;
+	}
+
+fallback:
+	if (alu == GXcopy && src_priv && src_priv->clear) {
+		DBG(("%s: copying clear [%08x]\n",
+		     __FUNCTION__, src_priv->clear_color));
+
+		RegionTranslate(&region, dst_dx, dst_dy);
+		box = REGION_RECTS(&region);
+		n = REGION_NUM_RECTS(&region);
+
+		if (dst_priv) {
+			assert_pixmap_contains_box(dst_pixmap,
+						   RegionExtents(&region));
+
+			if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable,
+							     &region,
+							     MOVE_WRITE | MOVE_INPLACE_HINT))
+				goto out;
+		}
+
+		do {
+			pixman_fill(dst_pixmap->devPrivate.ptr,
+				    dst_pixmap->devKind/sizeof(uint32_t),
+				    dst_pixmap->drawable.bitsPerPixel,
+				    box->x1, box->y1,
+				    box->x2 - box->x1,
+				    box->y2 - box->y1,
+				    src_priv->clear_color);
+			box++;
+		} while (--n);
 	} else {
 		FbBits *dst_bits, *src_bits;
 		int dst_stride, src_stride;
 
-fallback:
 		DBG(("%s: fallback -- src=(%d, %d), dst=(%d, %d)\n",
 		     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy));
 		if (src_priv) {
@@ -3351,9 +3470,10 @@ fallback:
 				      alu, -1, bpp,
 				      reverse, upsidedown);
 				box++;
-			}while (--n);
+			} while (--n);
 		}
 	}
+
 out:
 	RegionUninit(&region);
 }
@@ -7219,6 +7339,18 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 					} else
 						sna_damage_add_box(damage, &r);
 				}
+
+				if ((gc->alu == GXcopy || gc->alu == GXclear) &&
+				    r.x2 - r.x1 == pixmap->drawable.width &&
+				    r.y2 - r.y1 == pixmap->drawable.height) {
+					struct sna_pixmap *priv = sna_pixmap(pixmap);
+
+					priv->clear = true;
+					priv->clear_color = gc->alu == GXcopy ? pixel : 0;
+
+					DBG(("%s: pixmap=%ld, marking clear [%08x]\n",
+					     __FUNCTION__, pixmap->drawable.serialNumber, priv->clear_color));
+				}
 			} else
 				success = false;
 		}
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 47eac63..6fb2d27 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -778,6 +778,19 @@ sna_composite_rectangles(CARD8		 op,
 			sna_damage_all(&priv->gpu_damage,
 				       pixmap->drawable.width, pixmap->drawable.height);
 			priv->undamaged = false;
+			if (op <= PictOpSrc) {
+				priv->clear = true;
+				priv->clear_color = 0;
+				if (op == PictOpSrc)
+					sna_get_pixel_from_rgba(&priv->clear_color,
+								color->red,
+								color->green,
+								color->blue,
+								color->alpha,
+								dst->format);
+				DBG(("%s: marking clear [%08x]\n",
+				     __FUNCTION__, priv->clear_color));
+			}
 		} else
 			sna_damage_add(&priv->gpu_damage, &region);
 	}
commit 67a166d1247a1197fc851308c33c4970868f6a21
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 22 13:46:05 2012 +0000

    sna: Pass inplace hint for sna_copy_boxes fallback
    
    In the unlikely event that this makes a difference, provide the hint as
    to when we do not read back from the destination and so a streaming copy
    would be preferable.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 37385eb..1e9ee16 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3283,9 +3283,10 @@ fallback:
 			assert_pixmap_contains_box(dst_pixmap,
 						   RegionExtents(&region));
 
-			mode = MOVE_WRITE;
-			if (alu != GXcopy)
-				mode |= MOVE_READ;
+			if (alu_overwrites(alu))
+				mode = MOVE_WRITE | MOVE_INPLACE_HINT;
+			else
+				mode = MOVE_WRITE | MOVE_READ;
 			if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable,
 							     &region, mode))
 				goto out;
commit 77ee92248582d65a03619d1bb1d93a74468eea00
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jan 22 13:42:57 2012 +0000

    sna: Use full usage flags for moving the dst pixmap for a copy
    
    Now that the migration code can decide for itself when to not move
    damage, we can pass the hints to the code rather than perform the
    optimisation in sna_copy_boxes.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 8801477..37385eb 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3090,7 +3090,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			goto fallback;
 		}
 
-		if (alu != GXcopy && !sna_pixmap_move_to_gpu(dst_pixmap, MOVE_READ | MOVE_WRITE)) {
+		if (!sna_pixmap_move_to_gpu(dst_pixmap,
+					    MOVE_WRITE | (alu_overwrites(alu) ? 0 : MOVE_READ))) {
 			DBG(("%s: fallback - not a pure copy and failed to move dst to GPU\n",
 			     __FUNCTION__));
 			goto fallback;
@@ -3121,9 +3122,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 					assert_pixmap_contains_box(dst_pixmap,
 								   RegionExtents(&region));
 					sna_damage_add(&dst_priv->gpu_damage, &region);
-					if (alu == GXcopy)
-						sna_damage_subtract(&dst_priv->cpu_damage,
-								    &region);
 					RegionTranslate(&region, -dst_dx, -dst_dy);
 				}
 			}
@@ -3152,9 +3150,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 					assert_pixmap_contains_box(dst_pixmap,
 								   RegionExtents(&region));
 					sna_damage_add(&dst_priv->gpu_damage, &region);
-					if (alu == GXcopy)
-						sna_damage_subtract(&dst_priv->cpu_damage,
-								    &region);
 					RegionTranslate(&region, -dst_dx, -dst_dy);
 				}
 			}
@@ -3262,8 +3257,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 								   RegionExtents(&region));
 					sna_damage_add(&dst_priv->gpu_damage,
 						       &region);
-					sna_damage_subtract(&dst_priv->cpu_damage,
-							    &region);
 					RegionTranslate(&region, -dst_dx, -dst_dy);
 				}
 			}


More information about the xorg-commit mailing list