xf86-video-intel: 7 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/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Aug 20 15:49:05 PDT 2012


 src/sna/gen2_render.c |    2 -
 src/sna/gen3_render.c |   68 +++++++++++++++++++++++++++++---------------------
 src/sna/gen4_render.c |   18 +++++++------
 src/sna/gen5_render.c |   17 ++++++------
 src/sna/gen6_render.c |   14 +++++-----
 src/sna/gen7_render.c |   17 ++++++------
 src/sna/kgem.c        |   44 ++++++++++++++++++++++++++------
 src/sna/kgem.h        |    6 ++--
 src/sna/sna.h         |    3 +-
 src/sna/sna_accel.c   |   14 ++++++++--
 10 files changed, 129 insertions(+), 74 deletions(-)

New commits:
commit c86df17c1455a53cb52f33a25c8c362e5331621e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 20 22:54:06 2012 +0100

    sna/gen3: Fix assertion to check the freshly allocated vertex bo
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 7fb5a08..ab94bdb 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1713,7 +1713,7 @@ static void gen3_vertex_close(struct sna *sna)
 			bo = kgem_create_linear(&sna->kgem,
 						4*sna->render.vertex_used, 0);
 			if (bo) {
-				assert(sna->render.vbo->snoop == false);
+				assert(bo->snoop == false);
 				kgem_bo_write(&sna->kgem, bo,
 					      sna->render.vertex_data,
 					      4*sna->render.vertex_used);
commit 6aabe90587f4916a01a1cd2bbc577a1e7fa20eca
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 20 22:09:54 2012 +0100

    sna: Allow target bo promotion to GPU even on old architectures
    
    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 f530603..9fda8ca 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2551,9 +2551,6 @@ use_cpu_bo:
 	if (priv->cpu_bo == NULL)
 		return NULL;
 
-	if (!to_sna_from_pixmap(pixmap)->kgem.can_blt_cpu)
-		return NULL;
-
 	if ((flags & FORCE_GPU) == 0 && !kgem_bo_is_busy(priv->cpu_bo))
 		return NULL;
 
@@ -2578,6 +2575,9 @@ use_cpu_bo:
 			goto move_to_gpu;
 	}
 
+	if (!to_sna_from_pixmap(pixmap)->kgem.can_blt_cpu)
+		return NULL;
+
 	if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, &region,
 					     MOVE_READ | MOVE_ASYNC_HINT)) {
 		DBG(("%s: failed to move-to-cpu, fallback\n", __FUNCTION__));
commit 1a4b6fea7b1516de35e6800efa5b85f8401a5b2a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 20 22:08:23 2012 +0100

    sna: Assign a unique id to snoopable CPU bo
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index c5b88ff..49e27d0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3309,6 +3309,7 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
 		assert(bo->snoop);
 		bo->refcnt = 1;
 		bo->pitch = stride;
+		bo->unique_id = kgem_get_unique_id(kgem);
 		return bo;
 	}
 
@@ -3331,6 +3332,7 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
 		}
 
 		bo->pitch = stride;
+		bo->unique_id = kgem_get_unique_id(kgem);
 		return bo;
 	}
 
@@ -3350,6 +3352,7 @@ struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
 
 		bo->map = MAKE_USER_MAP(ptr);
 		bo->pitch = stride;
+		bo->unique_id = kgem_get_unique_id(kgem);
 		return bo;
 	}
 
commit 892b1a1e431e8f27133825f8a27dde4955da0054
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 20 22:07:05 2012 +0100

    sna/gen3: Convert to sna_drawable_use_bo()
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 81d2c95..7fb5a08 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2483,37 +2483,48 @@ gen3_align_vertex(struct sna *sna,
 static bool
 gen3_composite_set_target(struct sna *sna,
 			  struct sna_composite_op *op,
-			  PicturePtr dst)
+			  PicturePtr dst,
+			  int x, int y, int w, int h)
 {
-	struct sna_pixmap *priv;
+	BoxRec box;
 
 	op->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
 	op->dst.format = dst->format;
 	op->dst.width = op->dst.pixmap->drawable.width;
 	op->dst.height = op->dst.pixmap->drawable.height;
 
-	op->dst.bo = NULL;
-	priv = sna_pixmap(op->dst.pixmap);
-	if (priv &&
-	    priv->gpu_bo == NULL &&
-	    priv->cpu_bo && priv->cpu_bo->domain != DOMAIN_CPU) {
-		op->dst.bo = priv->cpu_bo;
-		op->damage = &priv->cpu_damage;
+	if (w && h) {
+		box.x1 = x;
+		box.y1 = y;
+		box.x2 = x + w;
+		box.y2 = y + h;
+	} else {
+		box.x1 = dst->pDrawable->x;
+		box.y1 = dst->pDrawable->y;
+		box.x2 = box.x1 + dst->pDrawable->width;
+		box.y2 = box.y1 + dst->pDrawable->height;
 	}
-	if (op->dst.bo == NULL) {
-		priv = sna_pixmap_force_to_gpu(op->dst.pixmap, MOVE_READ | MOVE_WRITE);
-		if (priv == NULL)
+
+	op->dst.bo = sna_drawable_use_bo (dst->pDrawable,
+					  PREFER_GPU | FORCE_GPU | RENDER_GPU,
+					  &box, &op->damage);
+	if (op->dst.bo == NULL)
+		return false;
+
+	/* For single-stream mode there should be no minimum alignment
+	 * required, except that the width must be at least 2 elements.
+	 */
+	if (op->dst.bo->pitch < 2*op->dst.pixmap->drawable.bitsPerPixel) {
+		struct sna_pixmap *priv;
+
+		priv = sna_pixmap_move_to_gpu (op->dst.pixmap,
+					       MOVE_READ | MOVE_WRITE);
+		if (priv == NULL || priv->pinned)
 			return false;
 
-		/* For single-stream mode there should be no minimum alignment
-		 * required, except that the width must be at least 2 elements.
-		 */
 		if (priv->gpu_bo->pitch < 2*op->dst.pixmap->drawable.bitsPerPixel) {
 			struct kgem_bo *bo;
 
-			if (priv->pinned)
-				return false;
-
 			bo = kgem_replace_bo(&sna->kgem, priv->gpu_bo,
 					     op->dst.width, op->dst.height,
 					     2*op->dst.pixmap->drawable.bitsPerPixel,
@@ -2524,13 +2535,13 @@ gen3_composite_set_target(struct sna *sna,
 			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
 			priv->gpu_bo = bo;
 		}
-		assert(priv->gpu_bo->proxy == NULL);
 
 		op->dst.bo = priv->gpu_bo;
 		op->damage = &priv->gpu_damage;
+		if (sna_damage_is_all(op->damage,
+				      op->dst.width, op->dst.height))
+			op->damage = NULL;
 	}
-	if (sna_damage_is_all(op->damage, op->dst.width, op->dst.height))
-		op->damage = NULL;
 
 	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
 			    &op->dst.x, &op->dst.y);
@@ -2543,6 +2554,7 @@ gen3_composite_set_target(struct sna *sna,
 	     op->dst.x, op->dst.y,
 	     op->damage ? *op->damage : (void *)-1));
 
+	assert(op->dst.bo->proxy == NULL);
 	return true;
 }
 
@@ -2832,14 +2844,13 @@ gen3_render_composite(struct sna *sna,
 					    width,  height,
 					    tmp);
 
-	if (!gen3_composite_set_target(sna, tmp, dst)) {
+	if (!gen3_composite_set_target(sna, tmp, dst,
+				       dst_x, dst_y, width, height)) {
 		DBG(("%s: unable to set render target\n",
 		     __FUNCTION__));
 		return false;
 	}
 
-	sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
-
 	tmp->op = op;
 	tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format);
 	if (too_large(tmp->dst.width, tmp->dst.height) ||
@@ -3421,12 +3432,12 @@ gen3_render_composite_spans(struct sna *sna,
 						  width, height, flags, tmp);
 	}
 
-	if (!gen3_composite_set_target(sna, &tmp->base, dst)) {
+	if (!gen3_composite_set_target(sna, &tmp->base, dst,
+				       dst_x, dst_y, width, height)) {
 		DBG(("%s: unable to set render target\n",
 		     __FUNCTION__));
 		return false;
 	}
-	sna_render_reduce_damage(&tmp->base, dst_x, dst_y, width, height);
 
 	tmp->base.op = op;
 	tmp->base.rb_reversed = gen3_dst_rb_reversed(tmp->base.dst.format);
diff --git a/src/sna/sna.h b/src/sna/sna.h
index cd55afd..157830b 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -464,7 +464,8 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling);
 
 #define PREFER_GPU	0x1
 #define FORCE_GPU	0x2
-#define IGNORE_CPU	0x4
+#define RENDER_GPU	0x4
+#define IGNORE_CPU	0x8
 struct kgem_bo *
 sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
 		    struct sna_damage ***damage);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e592b10..f530603 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2570,6 +2570,14 @@ use_cpu_bo:
 	if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo))
 		goto move_to_gpu;
 
+	if (flags & RENDER_GPU) {
+		if (priv->gpu_bo && priv->gpu_bo->tiling)
+			goto move_to_gpu;
+
+		if (priv->cpu_bo->pitch >= 4096)
+			goto move_to_gpu;
+	}
+
 	if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, &region,
 					     MOVE_READ | MOVE_ASYNC_HINT)) {
 		DBG(("%s: failed to move-to-cpu, fallback\n", __FUNCTION__));
commit 3ca1bfb51ba522454433d58131e7dab7fcbe7e34
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 20 21:28:47 2012 +0100

    sna: Trim a parameter from kgem_bo_mark_dirty() and add some assertions
    
    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 fea1791..9e51cb7 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -547,7 +547,7 @@ static void gen2_emit_target(struct sna *sna, const struct sna_composite_op *op)
 	assert(sna->render_state.gen2.vertex_offset == 0);
 
 	if (sna->render_state.gen2.target == op->dst.bo->unique_id) {
-		kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+		kgem_bo_mark_dirty(op->dst.bo);
 		return;
 	}
 
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 72a2575..81d2c95 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1342,6 +1342,7 @@ static void gen3_emit_target(struct sna *sna,
 	struct gen3_render_state *state = &sna->render_state.gen3;
 
 	/* BUF_INFO is an implicit flush, so skip if the target is unchanged. */
+	assert(bo->unique_id != 0);
 	if (bo->unique_id != state->current_dst) {
 		uint32_t v;
 
@@ -1373,7 +1374,7 @@ static void gen3_emit_target(struct sna *sna,
 
 		state->current_dst = bo->unique_id;
 	}
-	kgem_bo_mark_dirty(&sna->kgem, bo);
+	kgem_bo_mark_dirty(bo);
 }
 
 static void gen3_emit_composite_state(struct sna *sna,
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index d72a2fd..632793f 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -654,15 +654,12 @@ gen4_bind_bo(struct sna *sna,
 	assert(!kgem_bo_is_snoop(bo));
 
 	/* After the first bind, we manage the cache domains within the batch */
-	if (is_dst) {
-		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
-		kgem_bo_mark_dirty(&sna->kgem, bo);
-	} else
-		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
 	offset = kgem_bo_get_binding(bo, format);
-	if (offset)
+	if (offset) {
+		if (is_dst)
+			kgem_bo_mark_dirty(bo);
 		return offset * sizeof(uint32_t);
+	}
 
 	offset = sna->kgem.surface -=
 		sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
@@ -671,6 +668,11 @@ gen4_bind_bo(struct sna *sna,
 	ss->ss0.surface_type = GEN4_SURFACE_2D;
 	ss->ss0.surface_format = format;
 
+	if (is_dst)
+		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
+	else
+		domains = I915_GEM_DOMAIN_SAMPLER << 16;
+
 	ss->ss0.data_return_format = GEN4_SURFACERETURNFORMAT_FLOAT32;
 	ss->ss0.color_blend = 1;
 	ss->ss1.base_addr =
@@ -1385,7 +1387,7 @@ gen4_emit_state(struct sna *sna,
 		     kgem_bo_is_dirty(op->mask.bo)));
 		OUT_BATCH(MI_FLUSH);
 		kgem_clear_dirty(&sna->kgem);
-		kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+		kgem_bo_mark_dirty(op->dst.bo);
 	}
 }
 
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 9b976c8..2894c58 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -639,16 +639,13 @@ gen5_bind_bo(struct sna *sna,
 	uint32_t *ss;
 
 	/* After the first bind, we manage the cache domains within the batch */
-	if (is_dst) {
-		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
-		kgem_bo_mark_dirty(&sna->kgem, bo);
-	} else
-		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
 	if (!DBG_NO_SURFACE_CACHE) {
 		offset = kgem_bo_get_binding(bo, format);
-		if (offset)
+		if (offset) {
+			if (is_dst)
+				kgem_bo_mark_dirty(bo);
 			return offset * sizeof(uint32_t);
+		}
 	}
 
 	offset = sna->kgem.surface -=
@@ -659,6 +656,10 @@ gen5_bind_bo(struct sna *sna,
 		 GEN5_SURFACE_BLEND_ENABLED |
 		 format << GEN5_SURFACE_FORMAT_SHIFT);
 
+	if (is_dst)
+		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
+	else
+		domains = I915_GEM_DOMAIN_SAMPLER << 16;
 	ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
 
 	ss[2] = ((width - 1)  << GEN5_SURFACE_WIDTH_SHIFT |
@@ -1387,7 +1388,7 @@ gen5_emit_state(struct sna *sna,
 	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
 		OUT_BATCH(MI_FLUSH);
 		kgem_clear_dirty(&sna->kgem);
-		kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+		kgem_bo_mark_dirty(op->dst.bo);
 	}
 }
 
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 710a35e..af8899e 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -903,7 +903,7 @@ gen6_emit_state(struct sna *sna,
 	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
 		gen6_emit_flush(sna);
 		kgem_clear_dirty(&sna->kgem);
-		kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+		kgem_bo_mark_dirty(op->dst.bo);
 		need_stall = false;
 	}
 	if (need_stall) {
@@ -1230,17 +1230,13 @@ gen6_bind_bo(struct sna *sna,
 	uint16_t offset;
 
 	/* After the first bind, we manage the cache domains within the batch */
-	if (is_dst) {
-		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
-		kgem_bo_mark_dirty(&sna->kgem, bo);
-	} else
-		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
 	offset = kgem_bo_get_binding(bo, format);
 	if (offset) {
 		DBG(("[%x]  bo(handle=%d), format=%d, reuse %s binding\n",
 		     offset, bo->handle, format,
 		     domains & 0xffff ? "render" : "sampler"));
+		if (is_dst)
+			kgem_bo_mark_dirty(bo);
 		return offset * sizeof(uint32_t);
 	}
 
@@ -1250,6 +1246,10 @@ gen6_bind_bo(struct sna *sna,
 	ss[0] = (GEN6_SURFACE_2D << GEN6_SURFACE_TYPE_SHIFT |
 		 GEN6_SURFACE_BLEND_ENABLED |
 		 format << GEN6_SURFACE_FORMAT_SHIFT);
+	if (is_dst)
+		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
+	else
+		domains = I915_GEM_DOMAIN_SAMPLER << 16;
 	ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
 	ss[2] = ((width - 1)  << GEN6_SURFACE_WIDTH_SHIFT |
 		 (height - 1) << GEN6_SURFACE_HEIGHT_SHIFT);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 8a281e5..d34cdfa 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -1047,7 +1047,7 @@ gen7_emit_state(struct sna *sna,
 			need_stall = GEN7_BLEND(op->u.gen7.flags) != NO_BLEND;
 		gen7_emit_pipe_invalidate(sna, need_stall);
 		kgem_clear_dirty(&sna->kgem);
-		kgem_bo_mark_dirty(&sna->kgem, op->dst.bo);
+		kgem_bo_mark_dirty(op->dst.bo);
 		need_stall = false;
 	}
 	if (need_stall)
@@ -1348,15 +1348,12 @@ gen7_bind_bo(struct sna *sna,
 	COMPILE_TIME_ASSERT(sizeof(struct gen7_surface_state) == 32);
 
 	/* After the first bind, we manage the cache domains within the batch */
-	if (is_dst) {
-		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
-		kgem_bo_mark_dirty(&sna->kgem, bo);
-	} else
-		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
 	offset = kgem_bo_get_binding(bo, format);
-	if (offset)
+	if (offset) {
+		if (is_dst)
+			kgem_bo_mark_dirty(bo);
 		return offset * sizeof(uint32_t);
+	}
 
 	offset = sna->kgem.surface -=
 		sizeof(struct gen7_surface_state) / sizeof(uint32_t);
@@ -1364,6 +1361,10 @@ gen7_bind_bo(struct sna *sna,
 	ss[0] = (GEN7_SURFACE_2D << GEN7_SURFACE_TYPE_SHIFT |
 		 gen7_tiling_bits(bo->tiling) |
 		 format << GEN7_SURFACE_FORMAT_SHIFT);
+	if (is_dst)
+		domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
+	else
+		domains = I915_GEM_DOMAIN_SAMPLER << 16;
 	ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
 	ss[2] = ((width - 1)  << GEN7_SURFACE_WIDTH_SHIFT |
 		 (height - 1) << GEN7_SURFACE_HEIGHT_SHIFT);
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 11cd6a4..c5b88ff 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1811,6 +1811,8 @@ static void kgem_commit(struct kgem *kgem)
 		}
 
 		kgem_retire(kgem);
+		assert(list_is_empty(&rq->buffers));
+
 		gem_close(kgem->fd, rq->bo->handle);
 	} else {
 		list_add_tail(&rq->list, &kgem->requests);
@@ -3551,6 +3553,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
 
 		if (bo->exec == NULL)
 			_kgem_add_bo(kgem, bo);
+		assert(bo->rq == kgem->next_request);
 
 		if (kgem->gen < 40 && read_write_domain & KGEM_RELOC_FENCED) {
 			if (bo->tiling &&
@@ -3568,7 +3571,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
 		kgem->reloc[index].presumed_offset = bo->presumed_offset;
 
 		if (read_write_domain & 0x7ff)
-			kgem_bo_mark_dirty(kgem, bo);
+			kgem_bo_mark_dirty(bo);
 
 		delta += bo->presumed_offset;
 	} else {
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 8227538..cf7cf70 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -534,15 +534,17 @@ static inline bool kgem_bo_is_dirty(struct kgem_bo *bo)
 	return bo->dirty;
 }
 
-static inline void kgem_bo_mark_dirty(struct kgem *kgem, struct kgem_bo *bo)
+static inline void kgem_bo_mark_dirty(struct kgem_bo *bo)
 {
 	if (bo->dirty)
 		return;
 
 	DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
 
+	assert(bo->exec);
+	assert(bo->rq);
 	bo->needs_flush = bo->dirty = true;
-	list_move(&bo->request, &kgem->next_request->buffers);
+	list_move(&bo->request, &bo->rq->buffers);
 }
 
 #define KGEM_BUFFER_WRITE	0x1
commit 16f3d3a9ae145a3af51d2c0c42c6c585d676a863
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 20 19:42:22 2012 +0100

    sna: Keep a stash of the most recently allocated requests
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 5441eed..11cd6a4 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -125,6 +125,7 @@ struct kgem_buffer {
 };
 
 static struct kgem_bo *__kgem_freed_bo;
+static struct kgem_request *__kgem_freed_request;
 static struct drm_i915_gem_exec_object2 _kgem_dummy_exec;
 
 static inline int bytes(struct kgem_bo *bo)
@@ -538,15 +539,28 @@ static struct kgem_request *__kgem_request_alloc(void)
 {
 	struct kgem_request *rq;
 
-	rq = malloc(sizeof(*rq));
-	if (rq == NULL)
-		rq = &_kgem_static_request;
+	rq = __kgem_freed_request;
+	if (rq) {
+		__kgem_freed_request = *(struct kgem_request **)rq;
+	} else {
+		rq = malloc(sizeof(*rq));
+		if (rq == NULL)
+			rq = &_kgem_static_request;
+	}
 
 	list_init(&rq->buffers);
+	rq->bo = NULL;
 
 	return rq;
 }
 
+static void __kgem_request_free(struct kgem_request *rq)
+{
+	_list_del(&rq->list);
+	*(struct kgem_request **)rq = __kgem_freed_request;
+	__kgem_freed_request = rq;
+}
+
 static struct list *inactive(struct kgem *kgem, int num_pages)
 {
 	return &kgem->inactive[cache_bucket(num_pages)];
@@ -1699,8 +1713,7 @@ static bool kgem_retire__requests(struct kgem *kgem)
 			}
 		}
 
-		_list_del(&rq->list);
-		free(rq);
+		__kgem_request_free(rq);
 	}
 
 #if HAS_DEBUG_FULL
@@ -1963,8 +1976,7 @@ static void kgem_cleanup(struct kgem *kgem)
 				kgem_bo_free(kgem, bo);
 		}
 
-		_list_del(&rq->list);
-		free(rq);
+		__kgem_request_free(rq);
 	}
 
 	kgem_close_inactive(kgem);
@@ -2303,6 +2315,11 @@ bool kgem_expire_cache(struct kgem *kgem)
 		free(bo);
 	}
 
+	while (__kgem_freed_request) {
+		struct kgem_request *rq = __kgem_freed_request;
+		__kgem_freed_request = *(struct kgem_request **)rq;
+		free(rq);
+	}
 
 	expire = 0;
 	list_for_each_entry(bo, &kgem->snoop, list) {
commit fb349ced91e15ecaa025321bd37d1fe3cfdd2f44
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 20 17:35:44 2012 +0100

    sna: A few more buffer cache management assertions
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 3cb9eb6..5441eed 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1333,6 +1333,9 @@ static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo)
 
 static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo)
 {
+	assert(bo->refcnt == 0);
+	assert(bo->exec == NULL);
+
 	if (num_pages(bo) > kgem->max_cpu_size >> 13) {
 		DBG(("%s handle=%d discarding large CPU buffer (%d >%d pages)\n",
 		     __FUNCTION__, bo->handle, num_pages(bo), kgem->max_cpu_size >> 13));
@@ -1953,7 +1956,9 @@ static void kgem_cleanup(struct kgem *kgem)
 
 			list_del(&bo->request);
 			bo->rq = NULL;
+			bo->exec = NULL;
 			bo->domain = DOMAIN_NONE;
+			bo->dirty = false;
 			if (bo->refcnt == 0)
 				kgem_bo_free(kgem, bo);
 		}


More information about the xorg-commit mailing list