xf86-video-intel: 3 commits - src/sna/gen6_render.c src/sna/kgem.c src/sna/sna_io.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Jan 10 16:45:55 PST 2012


 src/sna/gen6_render.c |   53 ++++++++++++++++++++++++-
 src/sna/kgem.c        |   40 ++++++++++---------
 src/sna/sna_io.c      |  104 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 177 insertions(+), 20 deletions(-)

New commits:
commit a93c93be76f6d5d2b481971349aabd15f282c3e8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jan 11 00:05:20 2012 +0000

    sna/gen6: Add a vertex program for a simple (affine, no rotation) spans
    
    I long for the day when this code is obsolete... Until then, this gives
    a nice boost in the fishtank.
    
    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 521b6f2..38d7f96 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2603,6 +2603,48 @@ gen6_emit_composite_spans_solid(struct sna *sna,
 }
 
 fastcall static void
+gen6_emit_composite_spans_simple(struct sna *sna,
+				 const struct sna_composite_spans_op *op,
+				 const BoxRec *box,
+				 float opacity)
+{
+	float *v;
+	union {
+		struct sna_coordinate p;
+		float f;
+	} dst;
+
+	float xx = op->base.src.transform->matrix[0][0];
+	float x0 = op->base.src.transform->matrix[0][2];
+	float yy = op->base.src.transform->matrix[1][1];
+	float y0 = op->base.src.transform->matrix[1][2];
+	float sx = op->base.src.scale[0];
+	float sy = op->base.src.scale[1];
+	int16_t tx = op->base.src.offset[0];
+	int16_t ty = op->base.src.offset[1];
+
+	v = sna->render.vertex_data + sna->render.vertex_used;
+	sna->render.vertex_used += 3*5;
+
+	dst.p.x = box->x2;
+	dst.p.y = box->y2;
+	v[0] = dst.f;
+	v[1] = ((box->x2 + tx) * xx + x0) * sx;
+	v[7] = v[2] = ((box->y2 + ty) * yy + y0) * sy;
+	v[13] = v[8] = v[3] = opacity;
+	v[9] = v[4] = 1;
+
+	dst.p.x = box->x1;
+	v[5] = dst.f;
+	v[11] = v[6] = ((box->x1 + tx) * xx + x0) * sx;
+
+	dst.p.y = box->y1;
+	v[10] = dst.f;
+	v[12] = ((box->y1 + ty) * yy + y0) * sy;
+	v[14] = 0;
+}
+
+fastcall static void
 gen6_emit_composite_spans_affine(struct sna *sna,
 				 const struct sna_composite_spans_op *op,
 				 const BoxRec *box,
@@ -2755,8 +2797,15 @@ gen6_render_composite_spans(struct sna *sna,
 	tmp->prim_emit = gen6_emit_composite_spans_primitive;
 	if (tmp->base.src.is_solid)
 		tmp->prim_emit = gen6_emit_composite_spans_solid;
-	else if (tmp->base.is_affine)
-		tmp->prim_emit = gen6_emit_composite_spans_affine;
+	else if (tmp->base.is_affine) {
+		if (tmp->base.src.transform->matrix[0][1] == 0 &&
+		    tmp->base.src.transform->matrix[1][0] == 0) {
+			tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2];
+			tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2];
+			tmp->prim_emit = gen6_emit_composite_spans_simple;
+		} else
+			tmp->prim_emit = gen6_emit_composite_spans_affine;
+	}
 	tmp->base.floats_per_vertex = 5 + 2*!tmp->base.is_affine;
 	tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
 
commit 3cf5da1090ac777044912ec24619d349d1f6b521
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 10 23:32:29 2012 +0000

    sna: Amalgamate small replacements into upload buffers
    
    Similar for the standard io paths, try to reuse an upload buffer for a
    small replacement pixmap.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 50fae25..3c17d3a 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -777,6 +777,107 @@ fallback:
 	sna->blt_state.fill_bo = 0;
 }
 
+static bool
+indirect_replace(struct sna *sna,
+		 PixmapPtr pixmap,
+		 struct kgem_bo *bo,
+		 const void *src, int stride)
+{
+	struct kgem *kgem = &sna->kgem;
+	struct kgem_bo *src_bo;
+	void *ptr;
+	bool ret;
+
+	if (pixmap->devKind * pixmap->drawable.height >> 12 > kgem->half_cpu_cache_pages)
+		return false;
+
+	if (bo->tiling == I915_TILING_Y || kgem->ring == KGEM_RENDER) {
+		BoxRec box;
+
+		src_bo = kgem_create_buffer_2d(kgem,
+					       pixmap->drawable.width,
+					       pixmap->drawable.height,
+					       pixmap->drawable.bitsPerPixel,
+					       KGEM_BUFFER_WRITE,
+					       &ptr);
+		if (!src_bo)
+			return false;
+
+		memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel,
+			   stride, src_bo->pitch,
+			   0, 0,
+			   0, 0,
+			   pixmap->drawable.width,
+			   pixmap->drawable.height);
+
+		box.x1 = box.y1 = 0;
+		box.x2 = pixmap->drawable.width;
+		box.y2 = pixmap->drawable.height;
+
+		ret = sna->render.copy_boxes(sna, GXcopy,
+					     pixmap, src_bo, 0, 0,
+					     pixmap, bo, 0, 0,
+					     &box, 1);
+	} else {
+		uint32_t cmd, br13, *b;
+
+		src_bo = kgem_create_buffer(kgem,
+					    stride * pixmap->drawable.height,
+					    KGEM_BUFFER_WRITE,
+					    &ptr);
+		if (!src_bo)
+			return false;
+
+		cmd = XY_SRC_COPY_BLT_CMD;
+		br13 = bo->pitch;
+		if (kgem->gen >= 40 && bo->tiling) {
+			cmd |= BLT_DST_TILED;
+			br13 >>= 2;
+		}
+		br13 |= 0xcc << 16;
+		switch (pixmap->drawable.bitsPerPixel) {
+		default:
+		case 32: cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
+			 br13 |= 1 << 25; /* RGB8888 */
+		case 16: br13 |= 1 << 24; /* RGB565 */
+		case 8: break;
+		}
+
+		kgem_set_mode(kgem, KGEM_BLT);
+		if (kgem->nexec + 2 > KGEM_EXEC_SIZE(kgem) ||
+		    kgem->nreloc + 2 > KGEM_RELOC_SIZE(kgem) ||
+		    !kgem_check_batch(kgem, 8) ||
+		    !kgem_check_bo_fenced(kgem, bo, NULL)) {
+			_kgem_submit(kgem);
+			_kgem_set_mode(kgem, KGEM_BLT);
+		}
+
+		memcpy(ptr, src, stride * pixmap->drawable.height);
+
+		b = kgem->batch + kgem->nbatch;
+		b[0] = cmd;
+		b[1] = br13;
+		b[2] = 0;
+		b[3] = pixmap->drawable.height << 16 | pixmap->drawable.width;
+		b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo,
+				      I915_GEM_DOMAIN_RENDER << 16 |
+				      I915_GEM_DOMAIN_RENDER |
+				      KGEM_RELOC_FENCED,
+				      0);
+		b[5] = 0;
+		b[6] = stride;
+		b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo,
+				      I915_GEM_DOMAIN_RENDER << 16 |
+				      KGEM_RELOC_FENCED,
+				      0);
+		kgem->nbatch += 8;
+		ret = true;
+	}
+
+	kgem_bo_destroy(kgem, src_bo);
+	return ret;
+}
+
 struct kgem_bo *sna_replace(struct sna *sna,
 			    PixmapPtr pixmap,
 			    struct kgem_bo *bo,
@@ -792,6 +893,9 @@ struct kgem_bo *sna_replace(struct sna *sna,
 	     pixmap->drawable.bitsPerPixel,
 	     bo->tiling));
 
+	if (indirect_replace(sna, pixmap, bo, src, stride))
+		return bo;
+
 	if (kgem_bo_is_busy(bo)) {
 		struct kgem_bo *new_bo;
 
commit f0e3f6b5bebf7471d3e3e84bd9b2d8469eb64093
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 10 22:12:41 2012 +0000

    sna: Check needs-flush status immediately upon destroy
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 27d271d..09e8ea2 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -905,29 +905,33 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	assert(list_is_empty(&bo->list));
 	if (bo->rq) {
 		DBG(("%s: handle=%d -> active\n", __FUNCTION__, bo->handle));
-		list_move(&bo->list, &kgem->active[bo->bucket]);
-	} else if (bo->needs_flush) {
+		list_add(&bo->list, &kgem->active[bo->bucket]);
+		return;
+	}
+
+	assert(bo->exec == NULL);
+	assert(list_is_empty(&bo->request));
+
+	if (bo->needs_flush &&
+	    (bo->needs_flush = kgem_busy(kgem, bo->handle))) {
 		DBG(("%s: handle=%d -> flushing\n", __FUNCTION__, bo->handle));
-		assert(list_is_empty(&bo->request));
 		list_add(&bo->request, &kgem->flushing);
-		list_move(&bo->list, &kgem->active[bo->bucket]);
+		list_add(&bo->list, &kgem->active[bo->bucket]);
 		bo->rq = &_kgem_static_request;
-	} else {
-		assert(bo->exec == NULL);
-		if (!IS_CPU_MAP(bo->map)) {
-			if (!kgem_bo_set_purgeable(kgem, bo)) {
-				kgem->need_purge |= bo->domain == DOMAIN_GPU;
-				goto destroy;
-			}
-			DBG(("%s: handle=%d, purged\n",
-			     __FUNCTION__, bo->handle));
-		}
+		return;
+	}
 
-		DBG(("%s: handle=%d -> inactive\n", __FUNCTION__, bo->handle));
-		kgem_bo_move_to_inactive(kgem, bo);
-		kgem->need_expire = true;
+	if (!IS_CPU_MAP(bo->map)) {
+		if (!kgem_bo_set_purgeable(kgem, bo)) {
+			kgem->need_purge |= bo->domain == DOMAIN_GPU;
+			goto destroy;
+		}
+		DBG(("%s: handle=%d, purged\n",
+		     __FUNCTION__, bo->handle));
 	}
 
+	DBG(("%s: handle=%d -> inactive\n", __FUNCTION__, bo->handle));
+	kgem_bo_move_to_inactive(kgem, bo);
 	return;
 
 destroy:
@@ -2577,7 +2581,7 @@ void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo, int prot)
 		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
 		drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
 
-		bo->needs_flush = !bo->flush;
+		bo->needs_flush = bo->flush;
 		if (bo->domain == DOMAIN_GPU)
 			kgem_retire(kgem);
 		bo->domain = DOMAIN_GTT;


More information about the xorg-commit mailing list