xf86-video-intel: 8 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Tue Jan 24 18:50:06 PST 2012


 src/sna/kgem.c       |   89 +++++++++++++++++++--------------------
 src/sna/sna.h        |    5 +-
 src/sna/sna_accel.c  |  116 ++++++++++++++++++++++++++++++++++++++++++---------
 src/sna/sna_driver.c |    3 -
 4 files changed, 146 insertions(+), 67 deletions(-)

New commits:
commit 338941eda3c7591a85b83000eafae0407d0d7cd0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 25 02:42:25 2012 +0000

    sna: Handle self-copies for CopyPlane
    
    Prepare the source first as this has the dual benefit of letting us
    decide how best to proceed with the op (on the CPU or GPU) and prevents
    modification of the damage after we have choosen our preferred path.
    
    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 f52766b..03dceaf 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4827,8 +4827,6 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
 	if (n == 0)
 		return;
 
-	if (!sna_pixmap_move_to_cpu(src_pixmap, MOVE_READ))
-		return;
 	get_drawable_deltas(source, src_pixmap, &dx, &dy);
 	sx += dx;
 	sy += dy;
@@ -5027,6 +5025,9 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	DBG(("%s: src=(%d, %d), dst=(%d, %d), size=%dx%d\n", __FUNCTION__,
 	     src_x, src_y, dst_x, dst_y, w, h));
 
+	if (gc->planemask == 0)
+		return NULL;
+
 	if (src->bitsPerPixel == 1 && (bit&1) == 0)
 		return miHandleExposures(src, dst, gc,
 					 src_x, src_y,
@@ -5068,6 +5069,17 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	if (!RegionNotEmpty(&region))
 		return NULL;
 
+	RegionTranslate(&region,
+			src_x - dst_x - dst->x + src->x,
+			src_y - dst_y - dst->y + src->y);
+
+	if (!sna_drawable_move_region_to_cpu(src, &region, MOVE_READ))
+		goto out;
+
+	RegionTranslate(&region,
+			-(src_x - dst_x - dst->x + src->x),
+			-(src_y - dst_y - dst->y + src->y));
+
 	if (FORCE_FALLBACK)
 		goto fallback;
 
@@ -5077,6 +5089,9 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	if (wedged(sna))
 		goto fallback;
 
+	if (!PM_IS_SOLID(dst, gc->planemask))
+		goto fallback;
+
 	if (sna_drawable_use_gpu_bo(dst, &region.extents, &damage)) {
 		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		if (priv->gpu_bo->tiling != I915_TILING_Y ||
@@ -5096,17 +5111,10 @@ fallback:
 	ret = NULL;
 	if (!sna_gc_move_to_cpu(gc, dst))
 		goto out;
-
 	if (!sna_drawable_move_region_to_cpu(dst, &region,
 					     MOVE_READ | MOVE_WRITE))
 		goto out;
 
-	RegionTranslate(&region,
-			src_x - dst_x - dst->x + src->x,
-			src_y - dst_y - dst->y + src->y);
-	if (!sna_drawable_move_region_to_cpu(src, &region, MOVE_READ))
-		goto out;
-
 	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);
commit 2e8b398ca383f5292adab8b351b8837dde3e131a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 25 01:42:56 2012 +0000

    sna: Only shrink partial buffers that are being written to
    
    Ignore inactive and mmapped buffers.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b979d3c..d85e930 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1255,54 +1255,55 @@ static void kgem_finish_partials(struct kgem *kgem)
 		}
 
 		assert(bo->base.rq == kgem->next_request);
-		if (bo->base.refcnt == 1 && bo->used < bo->base.size / 2) {
-			struct kgem_bo *shrink;
-
-			shrink = search_linear_cache(kgem,
-						     PAGE_ALIGN(bo->used),
-						     CREATE_INACTIVE);
-			if (shrink) {
-				int n;
-
-				DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n",
-				     __FUNCTION__,
-				     bo->used, bo->base.size, shrink->size,
-				     bo->base.handle, shrink->handle));
-
-				assert(bo->used <= shrink->size);
-				gem_write(kgem->fd, shrink->handle,
-					  0, bo->used, bo->mem);
-
-				for (n = 0; n < kgem->nreloc; n++) {
-					if (kgem->reloc[n].target_handle == bo->base.handle) {
-						kgem->reloc[n].target_handle = shrink->handle;
-						kgem->reloc[n].presumed_offset = shrink->presumed_offset;
-						kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
-							kgem->reloc[n].delta + shrink->presumed_offset;
+		if (bo->used && bo->need_io) {
+			if (bo->base.refcnt == 1 &&
+			    bo->used < bo->base.size / 2) {
+				struct kgem_bo *shrink;
+
+				shrink = search_linear_cache(kgem,
+							     PAGE_ALIGN(bo->used),
+							     CREATE_INACTIVE);
+				if (shrink) {
+					int n;
+
+					DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n",
+					     __FUNCTION__,
+					     bo->used, bo->base.size, shrink->size,
+					     bo->base.handle, shrink->handle));
+
+					assert(bo->used <= shrink->size);
+					gem_write(kgem->fd, shrink->handle,
+						  0, bo->used, bo->mem);
+
+					for (n = 0; n < kgem->nreloc; n++) {
+						if (kgem->reloc[n].target_handle == bo->base.handle) {
+							kgem->reloc[n].target_handle = shrink->handle;
+							kgem->reloc[n].presumed_offset = shrink->presumed_offset;
+							kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] =
+								kgem->reloc[n].delta + shrink->presumed_offset;
+						}
 					}
-				}
-
-				bo->base.exec->handle = shrink->handle;
-				bo->base.exec->offset = shrink->presumed_offset;
-				shrink->exec = bo->base.exec;
-				shrink->rq = bo->base.rq;
-				list_replace(&bo->base.request,
-					     &shrink->request);
-				list_init(&bo->base.request);
-				shrink->needs_flush = bo->base.dirty;
-
-				bo->base.exec = NULL;
-				bo->base.rq = NULL;
-				bo->base.dirty = false;
-				bo->base.needs_flush = false;
-				bo->used = 0;
 
-				bubble_sort_partial(kgem, bo);
-				continue;
+					bo->base.exec->handle = shrink->handle;
+					bo->base.exec->offset = shrink->presumed_offset;
+					shrink->exec = bo->base.exec;
+					shrink->rq = bo->base.rq;
+					list_replace(&bo->base.request,
+						     &shrink->request);
+					list_init(&bo->base.request);
+					shrink->needs_flush = bo->base.dirty;
+
+					bo->base.exec = NULL;
+					bo->base.rq = NULL;
+					bo->base.dirty = false;
+					bo->base.needs_flush = false;
+					bo->used = 0;
+
+					bubble_sort_partial(kgem, bo);
+					continue;
+				}
 			}
-		}
 
-		if (bo->used && bo->need_io) {
 			DBG(("%s: handle=%d, uploading %d/%d\n",
 			     __FUNCTION__, bo->base.handle, bo->used, bo->base.size));
 			assert(!kgem_busy(kgem, bo->base.handle));
commit b79252efaafe2ebc998d6cf6176a425dd897e66f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 25 01:36:27 2012 +0000

    sna: Apply source clipping to sna_copy_plane()
    
    Ensure that the migration region is within bounds for both the source
    and destination pixmaps.
    
    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 2d83868..f52766b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5038,7 +5038,33 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	region.extents.x2 = region.extents.x1 + w;
 	region.extents.y2 = region.extents.y1 + h;
 	region.data = NULL;
-	region_maybe_clip(&region, gc->pCompositeClip);
+	RegionIntersect(&region, &region, gc->pCompositeClip);
+
+	DBG(("%s: dst extents (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
+
+	{
+		RegionRec clip;
+
+		clip.extents.x1 = src->x - (src->x + src_x) + (dst->x + dst_x);
+		clip.extents.y1 = src->y - (src->y + src_y) + (dst->y + dst_y);
+		clip.extents.x2 = clip.extents.x1 + src->width;
+		clip.extents.y2 = clip.extents.y1 + src->height;
+		clip.data = NULL;
+
+		DBG(("%s: src extents (%d, %d), (%d, %d)\n",
+		     __FUNCTION__,
+		     clip.extents.x1, clip.extents.y1,
+		     clip.extents.x2, clip.extents.y2));
+
+		RegionIntersect(&region, &region, &clip);
+	}
+	DBG(("%s: dst^src extents (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     region.extents.x1, region.extents.y1,
+	     region.extents.x2, region.extents.y2));
 	if (!RegionNotEmpty(&region))
 		return NULL;
 
commit 46252bc7bcc7e08e47d00cdc87d6c1ed93830fcc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 25 01:31:34 2012 +0000

    sna: Set the source clip for CopyArea fallback correctly
    
    The source window is (src->x, src->y)x(src->width, src->height) in
    pixmap space. However, we then need to use this to clip against the
    desination region, and so we need to translate from the source
    coordinate to the destination coordinate.
    
    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 f86bb62..2d83868 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3629,8 +3629,8 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		{
 			RegionRec clip;
 
-			clip.extents.x1 = -(src_x - dst_x - dst->x + src->x);
-			clip.extents.y1 = -(src_y - dst_y - dst->y + src->y);
+			clip.extents.x1 = src->x - (src->x + src_x) + (dst->x + dst_x);
+			clip.extents.y1 = src->y - (src->y + src_y) + (dst->y + dst_y);
 			clip.extents.x2 = clip.extents.x1 + src->width;
 			clip.extents.y2 = clip.extents.y1 + src->height;
 			clip.data = NULL;
commit ae6d3a311783d7e063de0347363331f14bd74d74
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 25 01:18:11 2012 +0000

    sna: Print source and destination regions for CopyArea fallback for DBG
    
    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 613c1ed..f86bb62 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3597,8 +3597,13 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 {
 	struct sna *sna = to_sna_from_drawable(dst);
 
-	DBG(("%s: src=(%d, %d)x(%d, %d) -> dst=(%d, %d)\n",
-	     __FUNCTION__, src_x, src_y, width, height, dst_x, dst_y));
+	if (gc->planemask == 0)
+		return NULL;
+
+	DBG(("%s: src=(%d, %d)x(%d, %d)+(%d, %d) -> dst=(%d, %d)+(%d, %d)\n",
+	     __FUNCTION__,
+	     src_x, src_y, width, height, src->x, src->y,
+	     dst_x, dst_y, dst->x, dst->y));
 
 	if (FORCE_FALLBACK || !ACCEL_COPY_AREA || wedged(sna) ||
 	    !PM_IS_SOLID(dst, gc->planemask)) {
@@ -3616,6 +3621,11 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		region.data = NULL;
 		RegionIntersect(&region, &region, gc->pCompositeClip);
 
+		DBG(("%s: dst extents (%d, %d), (%d, %d)\n",
+		     __FUNCTION__,
+		     region.extents.x1, region.extents.y1,
+		     region.extents.x2, region.extents.y2));
+
 		{
 			RegionRec clip;
 
@@ -3625,8 +3635,18 @@ sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			clip.extents.y2 = clip.extents.y1 + src->height;
 			clip.data = NULL;
 
+			DBG(("%s: src extents (%d, %d), (%d, %d)\n",
+			     __FUNCTION__,
+			     clip.extents.x1, clip.extents.y1,
+			     clip.extents.x2, clip.extents.y2));
+
 			RegionIntersect(&region, &region, &clip);
 		}
+		DBG(("%s: dst^src extents (%d, %d), (%d, %d)\n",
+		     __FUNCTION__,
+		     region.extents.x1, region.extents.y1,
+		     region.extents.x2, region.extents.y2));
+
 		if (!RegionNotEmpty(&region))
 			return NULL;
 
commit dd5e90adfc73870cebcb215ad9fb9b5aedd38673
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 25 01:17:49 2012 +0000

    sna: Clip GetImage to drawable so that damage migration is within bounds
    
    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 31a9079..613c1ed 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1143,7 +1143,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	     RegionExtents(region)->x2, RegionExtents(region)->y2,
 	     flags));
 
-	assert_pixmap_contains_box(pixmap, &region->extents);
+	assert_drawable_contains_box(drawable, &region->extents);
 
 	priv = sna_pixmap(pixmap);
 	if (priv == NULL) {
@@ -11102,6 +11102,16 @@ sna_get_image(DrawablePtr drawable,
 	region.extents.y2 = region.extents.y1 + h;
 	region.data = NULL;
 
+	if (region.extents.x1 < drawable->x)
+		region.extents.x1 = drawable->x;
+	if (region.extents.x2 > drawable->x + drawable->width)
+		region.extents.x2 = drawable->x + drawable->width;
+
+	if (region.extents.y1 < drawable->y)
+		region.extents.y1 = drawable->y;
+	if (region.extents.y2 > drawable->y + drawable->height)
+		region.extents.y2 = drawable->y + drawable->height;
+
 	if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_READ))
 		return;
 
commit b1fba5e8534da7fe253e21a3501854c04d82a108
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 25 01:16:34 2012 +0000

    sna: Clear GPU damage first when moving a clear pixmap to the CPU
    
    This allows us to discard any busy GPU or CPU bo when we know we are
    going to clear the shadow pixmap afterwards.
    
    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 1a13465..31a9079 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -922,6 +922,13 @@ skip_inplace_map:
 		priv->mapped = false;
 	}
 
+	if (priv->clear) {
+		if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo))
+			sna_pixmap_free_cpu(sna, priv);
+		sna_damage_destroy(&priv->gpu_damage);
+		priv->undamaged = true;
+	}
+
 	if (pixmap->devPrivate.ptr == NULL &&
 	    !sna_pixmap_alloc_cpu(sna, pixmap, priv, priv->gpu_damage != NULL))
 		return false;
@@ -943,8 +950,6 @@ skip_inplace_map:
 			    pixmap->drawable.height,
 			    priv->clear_color);
 
-		sna_damage_destroy(&priv->gpu_damage);
-		priv->undamaged = true;
 		priv->clear = false;
 	}
 
commit 5ad95d66665802bce25e127ae0d06f3e0a9b0e62
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 24 22:11:20 2012 +0000

    sna: Reduce number of reads required to inspect timers
    
    By using the information provided by select at wakeup.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index cabf04c..d8f96e0 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -231,7 +231,8 @@ struct sna {
 #define SNA_NO_DELAYED_FLUSH	0x2
 
 	int timer[NUM_TIMERS];
-	int timer_active;
+	uint16_t timer_active;
+	uint16_t timer_ready;
 
 	int vblank_interval;
 
@@ -581,7 +582,7 @@ static inline uint32_t pixmap_size(PixmapPtr pixmap)
 Bool sna_accel_pre_init(struct sna *sna);
 Bool sna_accel_init(ScreenPtr sreen, struct sna *sna);
 void sna_accel_block_handler(struct sna *sna);
-void sna_accel_wakeup_handler(struct sna *sna);
+void sna_accel_wakeup_handler(struct sna *sna, fd_set *ready);
 void sna_accel_close(struct sna *sna);
 void sna_accel_free(struct sna *sna);
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 46016e0..1a13465 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -11276,7 +11276,7 @@ static void _sna_accel_disarm_timer(struct sna *sna, int id)
 
 #define return_if_timer_active(id) do {					\
 	if (sna->timer_active & (1<<(id)))				\
-		return read_timer(sna->timer[id]) > 0;			\
+		return (sna->timer_ready & (1<<(id))) && read_timer(sna->timer[id]) > 0;			\
 } while (0)
 
 static Bool sna_accel_do_flush(struct sna *sna)
@@ -11687,15 +11687,24 @@ void sna_accel_block_handler(struct sna *sna)
 
 	if (sna_accel_do_inactive(sna))
 		sna_accel_inactive(sna);
+
+	sna->timer_ready = 0;
 }
 
-void sna_accel_wakeup_handler(struct sna *sna)
+void sna_accel_wakeup_handler(struct sna *sna, fd_set *ready)
 {
+	int id, active;
+
 	if (sna->kgem.need_retire)
 		kgem_retire(&sna->kgem);
 	if (sna->kgem.need_purge)
 		kgem_purge_cache(&sna->kgem);
 
+	active = sna->timer_active & ~sna->timer_ready;
+	for (id = 0; id < NUM_TIMERS; id++)
+		if (active & (1 << id) && FD_ISSET(sna->timer[id], ready))
+			sna->timer_ready |= 1 << id;
+
 	sna_deferred_free(sna);
 }
 
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 770a5bd..bcd1191 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -606,7 +606,7 @@ sna_wakeup_handler(int i, pointer data, unsigned long result, pointer read_mask)
 
 	sna->WakeupHandler(i, sna->WakeupData, result, read_mask);
 
-	sna_accel_wakeup_handler(sna);
+	sna_accel_wakeup_handler(sna, read_mask);
 
 	if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask))
 		sna_dri_wakeup(sna);
@@ -761,7 +761,6 @@ static Bool sna_close_screen(int scrnIndex, ScreenPtr screen)
 #endif
 
 	/* drain the event queues */
-	sna_accel_wakeup_handler(sna);
 	if (sna_dri_has_pending_events(sna))
 		sna_dri_wakeup(sna);
 


More information about the xorg-commit mailing list