xf86-video-intel: 3 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/gen8_render.c src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_composite.c src/sna/sna_display.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Tue Apr 15 09:02:05 PDT 2014


 src/sna/gen2_render.c   |    2 +-
 src/sna/gen3_render.c   |    2 +-
 src/sna/gen4_render.c   |    2 +-
 src/sna/gen5_render.c   |    2 +-
 src/sna/gen6_render.c   |    2 +-
 src/sna/gen7_render.c   |    2 +-
 src/sna/gen8_render.c   |    2 +-
 src/sna/kgem.c          |   41 +++++++++++++++++++++++++++++++++++++++++
 src/sna/sna.h           |    2 ++
 src/sna/sna_accel.c     |   41 ++++++++++++++++++++++++++++++++---------
 src/sna/sna_composite.c |    3 ++-
 src/sna/sna_display.c   |   25 +++++++++++++++++++++++--
 12 files changed, 107 insertions(+), 19 deletions(-)

New commits:
commit fd0579016be9e0385c0cdd07a9f9e17f93b93a4f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 15 16:27:44 2014 +0100

    sna: Pre-emptively move framebuffers into the DISPLAY cache domain
    
    In order to avoid rendering to the bo and then stalling before we can
    pin it the display plane, allocate bo for fb from uncached and change
    the cache level during the initial allocation.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=77436
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 0b8af54..a840ed6 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4168,6 +4168,35 @@ __kgem_bo_create_as_display(struct kgem *kgem, int size, int tiling, int pitch)
 	return bo;
 }
 
+static void __kgem_bo_make_scanout(struct kgem *kgem,
+				   struct kgem_bo *bo,
+				   int width, int height)
+{
+	ScrnInfoPtr scrn =
+		container_of(kgem, struct sna, kgem)->scrn;
+	struct drm_mode_fb_cmd arg;
+
+	if (!scrn->vtSema)
+		return;
+
+	DBG(("%s: create fb %dx%d@%d/%d\n",
+	     __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
+
+	VG_CLEAR(arg);
+	arg.width = width;
+	arg.height = height;
+	arg.pitch = bo->pitch;
+	arg.bpp = scrn->bitsPerPixel;
+	arg.depth = scrn->depth;
+	arg.handle = bo->handle;
+
+	if (gem_set_caching(kgem->fd, bo->handle, DISPLAY) &&
+	    do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg) == 0) {
+		bo->scanout = true;
+		bo->delta = arg.fb_id;
+	}
+}
+
 struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			       int width,
 			       int height,
@@ -4295,6 +4324,8 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 		bo = __kgem_bo_create_as_display(kgem, size, tiling, pitch);
 		if (bo)
 			return bo;
+
+		flags |= CREATE_INACTIVE;
 	}
 
 	if (bucket >= NUM_CACHE_BUCKETS) {
@@ -4386,6 +4417,10 @@ large_inactive:
 			assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
 			assert_tiling(kgem, bo);
 			bo->refcnt = 1;
+
+			if (flags & CREATE_SCANOUT)
+				__kgem_bo_make_scanout(kgem, bo, width, height);
+
 			return bo;
 		}
 
@@ -4691,6 +4726,10 @@ search_inactive:
 		assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo));
 		assert_tiling(kgem, bo);
 		bo->refcnt = 1;
+
+		if (flags & CREATE_SCANOUT)
+			__kgem_bo_make_scanout(kgem, bo, width, height);
+
 		return bo;
 	}
 
@@ -4728,6 +4767,8 @@ create:
 	    gem_set_tiling(kgem->fd, handle, tiling, pitch)) {
 		bo->tiling = tiling;
 		bo->pitch = pitch;
+		if (flags & CREATE_SCANOUT)
+			__kgem_bo_make_scanout(kgem, bo, width, height);
 	} else {
 		if (flags & CREATE_EXACT) {
 			gem_close(kgem->fd, handle);
commit b0472af1f3c6832838b0cfea38e261c908afd04e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 15 16:31:08 2014 +0100

    sna: Mark partial composite operations upfront
    
    Rather than guess in the backend when we are going to be called for
    multiple boxes, rely on the frontend declaring it correctly.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index a6c24f7..f51d6cf 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1904,7 +1904,7 @@ gen2_render_composite(struct sna *sna,
 
 	if (!gen2_composite_set_target(sna, tmp, dst,
 				       dst_x, dst_y, width, height,
-				       flags & COMPOSITE_PARTIAL || op > PictOpSrc || dst->pCompositeClip->data != NULL)) {
+				       flags & COMPOSITE_PARTIAL || op > PictOpSrc)) {
 		DBG(("%s: unable to set render target\n",
 		     __FUNCTION__));
 		goto fallback;
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 1bfc509..6ba1bb4 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -3515,7 +3515,7 @@ gen3_render_composite(struct sna *sna,
 
 	if (!gen3_composite_set_target(sna, tmp, dst,
 				       dst_x, dst_y, width, height,
-				       flags & COMPOSITE_PARTIAL || op > PictOpSrc || dst->pCompositeClip->data)) {
+				       flags & COMPOSITE_PARTIAL || op > PictOpSrc)) {
 		DBG(("%s: unable to set render target\n",
 		     __FUNCTION__));
 		goto fallback;
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index ee96f6c..f74757b 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1948,7 +1948,7 @@ gen4_render_composite(struct sna *sna,
 
 	if (!gen4_composite_set_target(sna, tmp, dst,
 				       dst_x, dst_y, width, height,
-				       flags & COMPOSITE_PARTIAL || op > PictOpSrc || dst->pCompositeClip->data)) {
+				       flags & COMPOSITE_PARTIAL || op > PictOpSrc)) {
 		DBG(("%s: failed to set composite target\n", __FUNCTION__));
 		goto fallback;
 	}
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 51a9714..67b0527 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1905,7 +1905,7 @@ gen5_render_composite(struct sna *sna,
 
 	if (!gen5_composite_set_target(sna, tmp, dst,
 				       dst_x, dst_y, width, height,
-				       flags & COMPOSITE_PARTIAL || op > PictOpSrc || dst->pCompositeClip->data)) {
+				       flags & COMPOSITE_PARTIAL || op > PictOpSrc)) {
 		DBG(("%s: failed to set composite target\n", __FUNCTION__));
 		goto fallback;
 	}
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 319cded..cb6f293 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2213,7 +2213,7 @@ gen6_render_composite(struct sna *sna,
 	tmp->op = op;
 	if (!gen6_composite_set_target(sna, tmp, dst,
 				       dst_x, dst_y, width, height,
-				       flags & COMPOSITE_PARTIAL || op > PictOpSrc || dst->pCompositeClip->data))
+				       flags & COMPOSITE_PARTIAL || op > PictOpSrc))
 		goto fallback;
 
 	switch (gen6_composite_picture(sna, src, &tmp->src,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 334958a..8d32c3e 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2468,7 +2468,7 @@ gen7_render_composite(struct sna *sna,
 	tmp->op = op;
 	if (!gen7_composite_set_target(sna, tmp, dst,
 				       dst_x, dst_y, width, height,
-				       flags & COMPOSITE_PARTIAL || op > PictOpSrc || dst->pCompositeClip->data))
+				       flags & COMPOSITE_PARTIAL || op > PictOpSrc))
 		goto fallback;
 
 	switch (gen7_composite_picture(sna, src, &tmp->src,
diff --git a/src/sna/gen8_render.c b/src/sna/gen8_render.c
index e680f74..0b7979e 100644
--- a/src/sna/gen8_render.c
+++ b/src/sna/gen8_render.c
@@ -2222,7 +2222,7 @@ gen8_render_composite(struct sna *sna,
 	tmp->op = op;
 	if (!gen8_composite_set_target(sna, tmp, dst,
 				       dst_x, dst_y, width, height,
-				       flags & COMPOSITE_PARTIAL || op > PictOpSrc || dst->pCompositeClip->data))
+				       flags & COMPOSITE_PARTIAL || op > PictOpSrc))
 		goto fallback;
 
 	switch (gen8_composite_picture(sna, src, &tmp->src,
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 5bcea88..13c9802 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -720,7 +720,8 @@ sna_composite(CARD8 op,
 				   region.extents.y1,
 				   region.extents.x2 - region.extents.x1,
 				   region.extents.y2 - region.extents.y1,
-				   0, memset(&tmp, 0, sizeof(tmp)))) {
+				   region.data ? COMPOSITE_PARTIAL : 0,
+				   memset(&tmp, 0, sizeof(tmp)))) {
 		DBG(("%s: fallback due unhandled composite op\n", __FUNCTION__));
 		goto fallback;
 	}
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index cb0d063..90c24fe 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4948,7 +4948,7 @@ sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo
 				   0, 0,
 				   0, 0,
 				   crtc->mode.HDisplay, crtc->mode.VDisplay,
-				   0, memset(&tmp, 0, sizeof(tmp)))) {
+				   COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) {
 		DBG(("%s: unsupported operation!\n", __FUNCTION__));
 		sna_crtc_redisplay__fallback(crtc, region, bo);
 		goto free_dst;
commit 49e72bd4e59085aa940e5af63381c5394ee670ad
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 15 11:24:10 2014 +0100

    sna: Discard TearFree readback when overdrawing
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=77436
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 3d4792c..00b12e9 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -377,6 +377,8 @@ extern void sna_mode_update(struct sna *sna);
 extern void sna_mode_reset(struct sna *sna);
 extern void sna_mode_wakeup(struct sna *sna);
 extern void sna_mode_redisplay(struct sna *sna);
+extern void sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
+					     RegionPtr region);
 extern void sna_mode_close(struct sna *sna);
 extern void sna_mode_fini(struct sna *sna);
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 50b4672..1f1a5a6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3131,10 +3131,24 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 	assert_pixmap_contains_box(pixmap, box);
 	assert(priv->gpu_damage == NULL || priv->gpu_bo);
 
-	if (priv->move_to_gpu &&
-	    !priv->move_to_gpu(sna, priv, flags | MOVE_READ | (priv->cpu_damage ? MOVE_WRITE : 0))) {
-		DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
-		return NULL;
+	if ((flags & MOVE_READ) == 0)
+		sna_damage_subtract_box(&priv->cpu_damage, box);
+
+	if (priv->move_to_gpu) {
+		unsigned int hint;
+
+		hint = flags | MOVE_READ | (priv->cpu_damage ? MOVE_WRITE : 0);
+		if ((flags & MOVE_READ) == 0) {
+			RegionRec region;
+
+			region.extents = *box;
+			region.data = NULL;
+			sna_pixmap_discard_shadow_damage(priv, &region);
+		}
+		if (!priv->move_to_gpu(sna, priv, hint)) {
+			DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
+			return NULL;
+		}
 	}
 
 	if (priv->cow && (flags & MOVE_WRITE || priv->cpu_damage)) {
@@ -3177,9 +3191,6 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 		priv->gpu_bo = NULL;
 	}
 
-	if ((flags & MOVE_READ) == 0)
-		sna_damage_subtract_box(&priv->cpu_damage, box);
-
 	sna_damage_reduce(&priv->cpu_damage);
 	assert_pixmap_damage(pixmap);
 
@@ -3652,14 +3663,26 @@ use_gpu_bo:
 	if (priv->move_to_gpu) {
 		unsigned hint = MOVE_READ | MOVE_WRITE;
 
+		sna = to_sna_from_pixmap(pixmap);
+
 		if (flags & IGNORE_CPU) {
 			region.extents = *box;
 			region.data = NULL;
-			if (region_subsumes_drawable(&region, &pixmap->drawable))
+			if (region_subsumes_pixmap(&region, pixmap)) {
+				DBG(("%s: discarding move-to-gpu READ for subsumed pixmap\n", __FUNCTION__));
 				hint = MOVE_WRITE;
+			} else {
+				if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+					region.extents.x1 += dx;
+					region.extents.x2 += dx;
+					region.extents.y1 += dy;
+					region.extents.y2 += dy;
+				}
+				sna_pixmap_discard_shadow_damage(priv, &region);
+			}
 		}
 
-		if (!priv->move_to_gpu(to_sna_from_pixmap(pixmap), priv, hint)) {
+		if (!priv->move_to_gpu(sna, priv, hint)) {
 			DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
 			goto use_cpu_bo;
 		}
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index b1f88a6..cb0d063 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -855,7 +855,7 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 
 	sna->mode.shadow_damage = damage;
 
-	if (flags & MOVE_READ) {
+	if (flags & MOVE_READ && RegionNotEmpty(&wait->region)) {
 		DBG(("%s: copying existing GPU damage: %ldx(%d, %d), (%d, %d)\n",
 		     __FUNCTION__, (long)REGION_NUM_RECTS(&wait->region),
 		     wait->region.extents.x1, wait->region.extents.y1,
@@ -887,6 +887,27 @@ done:
 	return ret;
 }
 
+void sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
+				      RegionPtr region)
+{
+	struct wait_for_shadow *wait = priv->move_to_gpu_data;
+
+	if (priv->move_to_gpu != wait_for_shadow)
+		return;
+
+	DBG(("%s: discarding region %dx[(%d, %d), (%d, %d)] from damage %dx[(%d, %d], (%d, %d)]\n",
+	     __FUNCTION__,
+	     RegionNumRects(region),
+	     region->extents.x1, region->extents.y1,
+	     region->extents.x2, region->extents.y2,
+	     RegionNumRects(&wait->region),
+	     wait->region.extents.x1, wait->region.extents.y1,
+	     wait->region.extents.x2, wait->region.extents.y2));
+
+	assert(wait);
+	RegionSubtract(&wait->region, &wait->region, region);
+}
+
 static bool sna_mode_enable_shadow(struct sna *sna)
 {
 	ScreenPtr screen = sna->scrn->pScreen;


More information about the xorg-commit mailing list