xf86-video-intel: 3 commits - src/sna/gen4_vertex.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_display.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Jun 23 00:11:54 PDT 2014
src/sna/gen4_vertex.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++---
src/sna/kgem.c | 51 +++++++++++++++++----
src/sna/kgem.h | 2
src/sna/sna_display.c | 1
4 files changed, 159 insertions(+), 15 deletions(-)
New commits:
commit a33aa554fa3df8ca34012cf1c6ecb11fa69ac7fc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jun 23 07:42:30 2014 +0100
sna/gen4+: Add box emitters for the generic vertex paths
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
index 0360b86..aaecb78 100644
--- a/src/sna/gen4_vertex.c
+++ b/src/sna/gen4_vertex.c
@@ -320,7 +320,7 @@ emit_texcoord(struct sna *sna,
int16_t x, int16_t y)
{
if (channel->is_solid) {
- OUT_VERTEX_F(x);
+ OUT_VERTEX_F(0.5);
return;
}
@@ -377,6 +377,63 @@ emit_primitive(struct sna *sna,
r->dst.x, r->dst.y);
}
+sse2 inline static float *
+vemit_texcoord(float *v,
+ const struct sna_composite_channel *channel,
+ int16_t x, int16_t y)
+{
+ if (channel->is_solid) {
+ *v++ = 0.5;
+ } else {
+ x += channel->offset[0];
+ y += channel->offset[1];
+
+ if (channel->is_affine) {
+ float s, t;
+
+ sna_get_transformed_coordinates(x, y,
+ channel->transform,
+ &s, &t);
+ *v++ = s * channel->scale[0];
+ *v++ = t * channel->scale[1];
+ } else {
+ float s, t, w;
+
+ sna_get_transformed_coordinates_3d(x, y,
+ channel->transform,
+ &s, &t, &w);
+ *v++ = s * channel->scale[0];
+ *v++ = t * channel->scale[1];
+ *v++ = w;
+ }
+ }
+
+ return v;
+}
+
+sse2 force_inline static float *
+vemit_vertex(float *v,
+ const struct sna_composite_op *op,
+ int16_t x, int16_t y)
+{
+ *v++ = pack_2s(x, y);
+ return vemit_texcoord(v, &op->src, x, y);
+}
+
+sse2 fastcall static void
+emit_boxes(const struct sna_composite_op *op,
+ const BoxRec *box, int nbox,
+ float *v)
+{
+ do {
+ v = vemit_vertex(v, op, box->x2, box->y2);
+ v = vemit_vertex(v, op, box->x1, box->y2);
+ v = vemit_vertex(v, op, box->x1, box->y1);
+
+ box++;
+ } while (--nbox);
+}
+
sse2 force_inline static void
emit_vertex_mask(struct sna *sna,
const struct sna_composite_op *op,
@@ -408,6 +465,32 @@ emit_primitive_mask(struct sna *sna,
r->dst.x, r->dst.y);
}
+sse2 force_inline static float *
+vemit_vertex_mask(float *v,
+ const struct sna_composite_op *op,
+ int16_t x, int16_t y)
+{
+ *v++ = pack_2s(x, y);
+ v = vemit_texcoord(v, &op->src, x, y);
+ v = vemit_texcoord(v, &op->mask, x, y);
+ return v;
+}
+
+sse2 fastcall static void
+emit_boxes_mask(const struct sna_composite_op *op,
+ const BoxRec *box, int nbox,
+ float *v)
+{
+ do {
+ v = vemit_vertex_mask(v, op, box->x2, box->y2);
+ v = vemit_vertex_mask(v, op, box->x1, box->y2);
+ v = vemit_vertex_mask(v, op, box->x1, box->y1);
+
+ box++;
+ } while (--nbox);
+}
+
+
sse2 fastcall static void
emit_primitive_solid(struct sna *sna,
const struct sna_composite_op *op,
@@ -1837,6 +1920,7 @@ unsigned gen4_choose_composite_emitter(struct sna *sna, struct sna_composite_op
}
} else {
tmp->prim_emit = emit_primitive_mask;
+ tmp->emit_boxes = emit_boxes_mask;
tmp->floats_per_vertex = 1;
vb = 0;
if (tmp->mask.is_solid) {
@@ -1943,6 +2027,7 @@ unsigned gen4_choose_composite_emitter(struct sna *sna, struct sna_composite_op
DBG(("%s: projective src, no mask\n", __FUNCTION__));
assert(!tmp->src.is_solid);
tmp->prim_emit = emit_primitive;
+ tmp->emit_boxes = emit_boxes;
tmp->floats_per_vertex = 4;
vb = 3;
}
@@ -1962,10 +2047,10 @@ emit_span_vertex(struct sna *sna,
}
sse2 fastcall static void
-emit_composite_spans_primitive(struct sna *sna,
- const struct sna_composite_spans_op *op,
- const BoxRec *box,
- float opacity)
+emit_span_primitive(struct sna *sna,
+ const struct sna_composite_spans_op *op,
+ const BoxRec *box,
+ float opacity)
{
emit_span_vertex(sna, op, box->x2, box->y2);
OUT_VERTEX_F(opacity);
@@ -1978,6 +2063,25 @@ emit_composite_spans_primitive(struct sna *sna,
}
sse2 fastcall static void
+emit_span_boxes(const struct sna_composite_spans_op *op,
+ const struct sna_opacity_box *b, int nbox,
+ float *v)
+{
+ do {
+ v = vemit_vertex(v, &op->base, b->box.x2, b->box.y2);
+ *v++ = b->alpha;
+
+ v = vemit_vertex(v, &op->base, b->box.x1, b->box.y2);
+ *v++ = b->alpha;
+
+ v = vemit_vertex(v, &op->base, b->box.x1, b->box.y1);
+ *v++ = b->alpha;
+
+ b++;
+ } while (--nbox);
+}
+
+sse2 fastcall static void
emit_span_solid(struct sna *sna,
const struct sna_composite_spans_op *op,
const BoxRec *box,
@@ -3085,7 +3189,8 @@ unsigned gen4_choose_spans_emitter(struct sna *sna,
vb = 1 << 2 | 2;
} else {
DBG(("%s: projective transform\n", __FUNCTION__));
- tmp->prim_emit = emit_composite_spans_primitive;
+ tmp->prim_emit = emit_span_primitive;
+ tmp->emit_boxes = emit_span_boxes;
tmp->base.floats_per_vertex = 5;
vb = 1 << 2 | 3;
}
commit 1909910fdf89216d18703e50728f4604f75d5d66
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jun 22 20:19:22 2014 +0100
sna: Inject a batch flush before adding a fresh bo
Fresh bo (those without a reservation already defined, ala
presumed_offset) will cause the kernel to do a full relocation pass. So,
if possible flush the already correct batch in the hope of trimming the
amount of checking the kernel has to perform on this new batch.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen4_vertex.c b/src/sna/gen4_vertex.c
index 4b3496c..0360b86 100644
--- a/src/sna/gen4_vertex.c
+++ b/src/sna/gen4_vertex.c
@@ -136,7 +136,8 @@ int gen4_vertex_finish(struct sna *sna)
if (sna->render.vbo == NULL)
sna->render.vbo = kgem_create_linear(&sna->kgem,
256*1024, CREATE_GTT_MAP);
- if (sna->render.vbo)
+ if (sna->render.vbo &&
+ kgem_check_bo(&sna->kgem, sna->render.vbo, NULL))
sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
if (sna->render.vertices == NULL) {
if (sna->render.vbo) {
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 03193c0..5e3c9f0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3017,6 +3017,8 @@ void kgem_reset(struct kgem *kgem)
kgem->nbatch = 0;
kgem->surface = kgem->batch_size;
kgem->mode = KGEM_NONE;
+ kgem->needs_semaphore = false;
+ kgem->needs_reservation = false;
kgem->flush = 0;
kgem->batch_flags = kgem->batch_flags_base;
@@ -5193,7 +5195,44 @@ void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo)
inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo)
{
- return kgem->nreloc && bo->rq && RQ_RING(bo->rq) != kgem->ring;
+ if (kgem->needs_semaphore)
+ return false;
+
+ if (bo->rq == NULL || RQ_RING(bo->rq) == kgem->ring)
+ return false;
+
+ kgem->needs_semaphore = true;
+ return true;
+}
+
+inline static bool needs_reservation(struct kgem *kgem, struct kgem_bo *bo)
+{
+ if (kgem->needs_reservation)
+ return false;
+
+ if (bo->presumed_offset || kgem_ring_is_idle(kgem, kgem->ring))
+ return false;
+
+ kgem->needs_reservation = true;
+ return true;
+}
+
+inline static bool needs_batch_flush(struct kgem *kgem, struct kgem_bo *bo)
+{
+ if (kgem->nreloc)
+ return false;
+
+ if (needs_semaphore(kgem, bo)) {
+ DBG(("%s: flushing before handle=%d for required semaphore\n", __FUNCTION__, bo->handle));
+ return true;
+ }
+
+ if (needs_reservation(kgem, bo)) {
+ DBG(("%s: flushing before handle=%d for new reservation\n", __FUNCTION__, bo->handle));
+ return true;
+ }
+
+ return false;
}
static bool aperture_check(struct kgem *kgem, unsigned num_pages)
@@ -5263,8 +5302,7 @@ bool kgem_check_bo(struct kgem *kgem, ...)
if (bo->exec)
continue;
- if (needs_semaphore(kgem, bo)) {
- DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
+ if (needs_batch_flush(kgem, bo)) {
va_end(ap);
return false;
}
@@ -5351,10 +5389,8 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
if (kgem->nexec >= KGEM_EXEC_SIZE(kgem) - 1)
return false;
- if (needs_semaphore(kgem, bo)) {
- DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
+ if (needs_batch_flush(kgem, bo))
return false;
- }
assert_tiling(kgem, bo);
if (kgem->gen < 040 && bo->tiling != I915_TILING_NONE) {
@@ -5432,8 +5468,7 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
continue;
}
- if (needs_semaphore(kgem, bo)) {
- DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
+ if (needs_batch_flush(kgem, bo)) {
va_end(ap);
return false;
}
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 5152a3b..e66bffb 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -171,6 +171,8 @@ struct kgem {
uint32_t need_purge:1;
uint32_t need_retire:1;
uint32_t need_throttle:1;
+ uint32_t needs_semaphore:1;
+ uint32_t needs_reservation:1;
uint32_t scanout_busy:1;
uint32_t busy:1;
commit 83cbbcd816e449402f3d49aeba3c099a20b8bc1b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jun 23 07:29:20 2014 +0100
sna: Add missing string for DBG
References: https://bugs.freedesktop.org/show_bug.cgi?id=80355#c12
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e7dd3d8..cb9526a 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1273,6 +1273,7 @@ bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
(RegionPtr)region);
} else {
DBG(("%s: discarding all damage %dx[(%d, %d], (%d, %d)]\n",
+ __FUNCTION__,
region_num_rects(&sna->mode.shadow_region),
sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
More information about the xorg-commit
mailing list