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