xf86-video-intel: 3 commits - src/sna/sna_dri2.c src/sna/sna_tiling.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jun 12 04:12:47 PDT 2015


 src/sna/sna_dri2.c   |   56 +++++++++++++++++++++++++++++++++++++++++++++------
 src/sna/sna_tiling.c |    4 +--
 2 files changed, 52 insertions(+), 8 deletions(-)

New commits:
commit a00d9999f410b3ad5bb05ed68b7dd4e7166fd868
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jun 12 10:33:17 2015 +0100

    sna: Fix tiling trapezoids
    
    When the trapezoid is rendering to a surface larger than the 3D pipe can
    handle, we split it into tiles. However, the code to do so insisted on
    passing along the wrong pointer and consequently crashed.
    
    Based on the patch by Carl Michal.
    
    Reported-by: Carl Michal <michal at physics.ubc.ca>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90940
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index 308efc0..8e2627f 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -369,8 +369,7 @@ sna_tiling_composite_spans_boxes(struct sna *sna,
 				 const BoxRec *box, int nbox, float opacity)
 {
 	while (nbox--)
-		sna_tiling_composite_spans_box(sna, op->base.priv, box++, opacity);
-	(void)sna;
+		sna_tiling_composite_spans_box(sna, op, box++, opacity);
 }
 
 fastcall static void
@@ -581,6 +580,7 @@ sna_tiling_composite_spans(uint32_t op,
 	tile->rects = tile->rects_embedded;
 	tile->rect_count = 0;
 	tile->rect_size = ARRAY_SIZE(tile->rects_embedded);
+	COMPILE_TIME_ASSERT(sizeof(tile->rects_embedded[0]) >= sizeof(struct sna_tile_span));
 
 	tmp->box   = sna_tiling_composite_spans_box;
 	tmp->boxes = sna_tiling_composite_spans_boxes;
commit dcb4d323ca19f86fbe0230378ac9035161a70f9e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 11 13:54:49 2015 +0100

    sna/dri2: Mark the pending backbuffer copy as active
    
    In order to perform swap elision for windows, we defer the blit until
    the next vblank and then do whatever was the last buffer to be presented
    by the client. Whilst that copy is pending, in the same manner as a
    pending flip, we cannot hand that buffer back to the client for use (or
    else they will render over top of it before we copy from it, or even
    worse we copy from it in the middle of rendering).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index e540066..f1c0491 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -69,7 +69,7 @@ static inline struct kgem_bo *ref(struct kgem_bo *bo)
 
 struct sna_dri2_private {
 	PixmapPtr pixmap;
-	struct kgem_bo *bo;
+	struct kgem_bo *bo, *copy;
 	DRI2Buffer2Ptr proxy;
 	bool stale;
 	uint32_t size;
@@ -298,6 +298,9 @@ sna_dri2_get_back(struct sna *sna,
 	back->name = name;
 	back->flags = flags;
 
+	assert(back->pitch);
+	assert(back->name);
+
 	get_private(back)->stale = false;
 }
 
@@ -381,7 +384,7 @@ sna_dri2_reuse_buffer(DrawablePtr draw, DRI2BufferPtr buffer)
 	     __FUNCTION__, get_drawable_pixmap(draw)->drawable.serialNumber,
 	     buffer->attachment, get_private(buffer)->bo->handle, buffer->name));
 	assert(get_private(buffer)->refcnt);
-	assert(get_private(buffer)->bo->refcnt > get_private(buffer)->bo->active_scanout);
+	assert(get_private(buffer)->bo->refcnt >= get_private(buffer)->bo->active_scanout);
 	assert(kgem_bo_flink(&to_sna_from_drawable(draw)->kgem, get_private(buffer)->bo) == buffer->name);
 
 	if (buffer->attachment == DRI2BufferBackLeft &&
@@ -391,7 +394,9 @@ sna_dri2_reuse_buffer(DrawablePtr draw, DRI2BufferPtr buffer)
 		assert(get_private(buffer)->bo->refcnt);
 		assert(get_private(buffer)->bo->active_scanout == 0);
 		assert(kgem_bo_flink(&to_sna_from_drawable(draw)->kgem, get_private(buffer)->bo) == buffer->name);
-		DBG(("reusing back buffer, age = %d\n", buffer->flags));
+		DBG(("%s: reusing back buffer handle=%d, name=%d, pitch=%d, age=%d\n",
+		     __FUNCTION__, get_private(buffer)->bo->handle,
+		     buffer->name, buffer->pitch, buffer->flags));
 	}
 }
 
@@ -2187,6 +2192,7 @@ static void fake_swap_complete(struct sna *sna, ClientPtr client,
 static void chain_swap(struct sna_dri2_event *chain)
 {
 	union drm_wait_vblank vbl;
+	struct kgem_bo *tmp;
 
 	if (chain->draw == NULL) {
 		sna_dri2_event_free(chain);
@@ -2221,6 +2227,24 @@ static void chain_swap(struct sna_dri2_event *chain)
 			DBG(("%s -- requeue failed, errno=%d\n", __FUNCTION__, errno));
 		}
 
+		/* We tracked the most recent completed swap in back->copy,
+		 * back->bo holds the buffer we last gave back to the client
+		 * i.e. its current render target. To simplify our swap
+		 * routines, we do an exchange here to emit the copy, then
+		 * exchange back again so that we are consistent with the
+		 * client once more.
+		 */
+		assert(get_private(chain->back)->copy);
+		DBG(("%s: removing active marker [%d] from handle=%d\n",
+		     __FUNCTION__,
+		     get_private(chain->back)->copy->active_scanout,
+		     get_private(chain->back)->copy->handle));
+		assert(get_private(chain->back)->copy->active_scanout);
+		get_private(chain->back)->copy->active_scanout--;
+
+		tmp = get_private(chain->back)->bo;
+		 get_private(chain->back)->bo = get_private(chain->back)->copy;
+
 		if (can_xchg(chain->sna, chain->draw, chain->front, chain->back)) {
 			sna_dri2_xchg(chain->draw, chain->front, chain->back);
 		} else if (can_xchg_crtc(chain->sna, chain->draw, chain->front, chain->back, chain->crtc)) {
@@ -2229,6 +2253,10 @@ static void chain_swap(struct sna_dri2_event *chain)
 			assert(chain->queued);
 			__sna_dri2_copy_event(chain, 0);
 		}
+		get_private(chain->back)->bo = tmp;
+		kgem_bo_destroy(&chain->sna->kgem,
+				get_private(chain->back)->copy);
+		get_private(chain->back)->copy = NULL;
 	case SWAP:
 		break;
 	default:
@@ -2438,6 +2466,21 @@ sna_dri2_immediate_blit(struct sna *sna,
 		return;
 	}
 
+	DBG(("%s: adding active marker [%d] to handle=%d, removing [%d] from handle=%d\n",
+	     __FUNCTION__,
+	     get_private(info->back)->bo->active_scanout,
+	     get_private(info->back)->bo->handle,
+	     get_private(info->back)->copy ? get_private(info->back)->copy->active_scanout : 0,
+	     get_private(info->back)->copy ? get_private(info->back)->copy->handle : 0));
+	if (get_private(info->back)->copy) {
+		get_private(info->back)->copy->active_scanout--;
+		kgem_bo_destroy(&info->sna->kgem,
+				get_private(info->back)->copy);
+	}
+	get_private(info->back)->copy = ref(get_private(info->back)->bo);
+	assert(get_private(info->back)->bo->active_scanout == 0);
+	get_private(info->back)->bo->active_scanout++;
+
 	if (chain->chain != info && chain->chain->type == SWAP_THROTTLE) {
 		struct sna_dri2_event *tmp = chain->chain;
 
commit 19d1e4ee19a93905d8d2496f856a18eb07bc23d6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 11 13:43:10 2015 +0100

    sna/dri2: Be wary of interactions with DRI3 and sna_pixmap->flush
    
    Since both DRI2 and DRI3 manipulate the sna_pixmap->flush flag, we have
    to relaxation assertions that it is wholly owned by DRI2.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 65c781c..e540066 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -462,7 +462,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 		return NULL;
 	}
 
-	assert(priv->flush == false);
+	assert(priv->flush == false || priv->pinned & PIN_DRI3);
 	assert(priv->cpu_damage == NULL);
 	assert(priv->gpu_bo);
 	assert(priv->gpu_bo->proxy == NULL);
@@ -699,7 +699,7 @@ sna_dri2_create_buffer(DrawablePtr draw,
 		pixmap->refcnt++;
 
 		priv = sna_pixmap(pixmap);
-		assert(priv->flush == false);
+		assert(priv->flush == false || priv->pinned & PIN_DRI3);
 		assert((priv->pinned & PIN_DRI2) == 0);
 
 		/* Don't allow this named buffer to be replaced */
@@ -780,7 +780,8 @@ static void _sna_dri2_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 		priv->gpu_bo->flush = false;
 		priv->pinned &= ~PIN_DRI2;
 
-		priv->flush = false;
+		if ((priv->pinned & PIN_DRI3) == 0)
+			priv->flush = false;
 		sna_accel_watch_flush(sna, -1);
 
 		sna_pixmap_set_buffer(pixmap, NULL);


More information about the xorg-commit mailing list