xf86-video-intel: 2 commits - src/sna/gen6_common.c src/sna/gen6_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Oct 31 14:55:55 CET 2013


 src/sna/gen6_common.c |    1 -
 src/sna/gen6_render.c |   11 ++++++-----
 src/sna/kgem.c        |   25 ++++++++++++++++---------
 src/sna/kgem.h        |    4 +++-
 src/sna/sna_accel.c   |    1 +
 5 files changed, 26 insertions(+), 16 deletions(-)

New commits:
commit 82e6d41c2f4f343bd1854d3d8ee4b624b5d68971
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 31 13:35:59 2013 +0000

    sna/gen6: Tweak flush around CC state changes
    
    In order to fix some font corruption, it appears that we need an extra
    flush in the Sandybridge pipeline when we change the CC stage and the
    render cache is dirty. We previously triggered a full pipeline stall
    for this case.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index f271cf8..9797ef9 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -866,21 +866,22 @@ gen6_emit_state(struct sna *sna,
 		const struct sna_composite_op *op,
 		uint16_t wm_binding_table)
 {
-	bool need_stall = wm_binding_table & 1;
+	bool need_flush, need_stall;
 
 	assert(op->dst.bo->exec);
 
-	if (gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags)))
-		need_stall = false;
+	need_flush =
+		gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags)) &&
+		wm_binding_table & 1;
 	gen6_emit_sampler(sna, GEN6_SAMPLER(op->u.gen6.flags));
 	gen6_emit_sf(sna, GEN6_VERTEX(op->u.gen6.flags) >> 2);
 	gen6_emit_wm(sna, GEN6_KERNEL(op->u.gen6.flags), GEN6_VERTEX(op->u.gen6.flags) >> 2);
 	gen6_emit_vertex_elements(sna, op);
 
-	need_stall |= gen6_emit_binding_table(sna, wm_binding_table & ~1);
+	need_stall = gen6_emit_binding_table(sna, wm_binding_table & ~1);
 	if (gen6_emit_drawing_rectangle(sna, op))
 		need_stall = false;
-	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
+	if (need_flush || kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
 		gen6_emit_flush(sna);
 		kgem_clear_dirty(&sna->kgem);
 		assert(op->dst.bo->exec);
commit 5cdc2bbc9c66d4c8c6fdb1b552c32177d070bf7b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 31 10:32:46 2013 +0000

    sna: Tweak deletion of used buffers
    
    Make sure we never unwind a used buffer.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_common.c b/src/sna/gen6_common.c
index 38af859..8789109 100644
--- a/src/sna/gen6_common.c
+++ b/src/sna/gen6_common.c
@@ -69,4 +69,3 @@ void gen6_render_retire(struct kgem *kgem)
 		sna->render.vertex_index = 0;
 	}
 }
-
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 7c0ad11..4c66917 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2357,6 +2357,7 @@ static void kgem_commit(struct kgem *kgem)
 
 		if (!bo->refcnt && !bo->reusable) {
 			assert(!bo->snoop);
+			assert(!bo->proxy);
 			kgem_bo_free(kgem, bo);
 			continue;
 		}
@@ -2451,8 +2452,8 @@ static void kgem_finish_buffers(struct kgem *kgem)
 			if (!DBG_NO_UPLOAD_ACTIVE &&
 			    used + PAGE_SIZE <= bytes(&bo->base) &&
 			    (kgem->has_llc || bo->mmapped == MMAPPED_GTT || bo->base.snoop)) {
-				DBG(("%s: retaining upload buffer (%d/%d)\n",
-				     __FUNCTION__, bo->used, bytes(&bo->base)));
+				DBG(("%s: retaining upload buffer (%d/%d): used=%d, refcnt=%d\n",
+				     __FUNCTION__, bo->used, bytes(&bo->base), used, bo->base.refcnt));
 				bo->used = used;
 				if (bo->base.refcnt == 1) {
 					list_move(&bo->base.list,
@@ -4634,17 +4635,22 @@ void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	     __FUNCTION__, bo->handle, bo->proxy != NULL));
 
 	if (bo->proxy) {
+		assert(!bo->reusable);
+		kgem_bo_binding_free(kgem, bo);
+
+		assert(list_is_empty(&bo->list));
 		_list_del(&bo->vma);
 		_list_del(&bo->request);
-		if (bo->io && bo->exec == NULL && bo->domain == DOMAIN_CPU)
+
+		if (bo->io && bo->domain == DOMAIN_CPU)
 			_kgem_bo_delete_buffer(kgem, bo);
+
 		kgem_bo_unref(kgem, bo->proxy);
-		kgem_bo_binding_free(kgem, bo);
-		free(bo);
-		return;
-	}
 
-	__kgem_bo_destroy(kgem, bo);
+		*(struct kgem_bo **)bo = __kgem_freed_bo;
+		__kgem_freed_bo = bo;
+	} else
+		__kgem_bo_destroy(kgem, bo);
 }
 
 static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
@@ -4993,6 +4999,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
 				bo->rq = MAKE_REQUEST(kgem->next_request,
 						      kgem->ring);
 				bo->exec = &_kgem_dummy_exec;
+				bo->domain = DOMAIN_GPU;
 			}
 
 			if (read_write_domain & 0x7fff && !bo->gpu_dirty)
@@ -5505,7 +5512,7 @@ struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
 	bo->proxy = kgem_bo_reference(target);
 	bo->delta = offset;
 
-	if (target->exec) {
+	if (target->exec && !bo->io) {
 		list_move_tail(&bo->request, &kgem->next_request->buffers);
 		bo->exec = &_kgem_dummy_exec;
 	}
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 77edfc8..e2bb4f9 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -370,8 +370,10 @@ static inline void kgem_set_mode(struct kgem *kgem,
 	kgem_submit(kgem);
 #endif
 
-	if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring))
+	if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) {
+		DBG(("%s: flushing before new bo\n", __FUNCTION__));
 		_kgem_submit(kgem);
+	}
 
 	if (kgem->mode == mode)
 		return;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 7d45065..93231db 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4264,6 +4264,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 		DBG(("%s: discarding cached upload proxy\n", __FUNCTION__));
 		sna_pixmap_free_gpu(sna, priv);
 	}
+	assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
 
 	if (priv->cow || priv->move_to_gpu) {
 		DBG(("%s: no, has COW or pending move-to-gpu\n", __FUNCTION__));


More information about the xorg-commit mailing list