xf86-video-intel: 5 commits - src/sna/gen3_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/sna_accel.c
Chris Wilson
ickle at kemper.freedesktop.org
Wed Sep 25 03:54:16 PDT 2013
src/sna/gen3_render.c | 47 --------------
src/sna/gen5_render.c | 28 --------
src/sna/gen6_render.c | 8 ++
src/sna/gen7_render.c | 8 ++
src/sna/kgem.c | 34 ++++++++--
src/sna/sna_accel.c | 157 ++++++++++++++++++++++++++++++--------------------
6 files changed, 136 insertions(+), 146 deletions(-)
New commits:
commit 598dae9af99495cb738c6ddbe8602f8fa19dc0df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Sep 25 10:53:11 2013 +0100
sna/gen[35]: Remove dead code for choosing between BLT/render composite
For these gen, we always want to use BLT where possible - even if it
incurs a context switch.
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 cb8f046..4c058e1 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -3119,52 +3119,6 @@ gen3_composite_picture(struct sna *sna,
x, y, w, h, dst_x, dst_y);
}
-static inline bool
-source_use_blt(struct sna *sna, PicturePtr picture)
-{
- /* If it is a solid, try to use the BLT paths */
- if (!picture->pDrawable)
- return picture->pSourcePict->type == SourcePictTypeSolidFill;
-
- if (picture->pDrawable->width == 1 &&
- picture->pDrawable->height == 1 &&
- picture->repeat)
- return true;
-
- if (too_large(picture->pDrawable->width, picture->pDrawable->height))
- return true;
-
- return !is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER);
-}
-
-static bool
-try_blt(struct sna *sna,
- PicturePtr dst,
- PicturePtr src,
- int width, int height)
-{
- if (sna->kgem.mode != KGEM_RENDER) {
- DBG(("%s: already performing BLT\n", __FUNCTION__));
- return true;
- }
-
- if (too_large(width, height)) {
- DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
- __FUNCTION__, width, height));
- return true;
- }
-
- if (too_large(dst->pDrawable->width, dst->pDrawable->height)) {
- DBG(("%s: target too large for 3D pipe (%d, %d)\n",
- __FUNCTION__,
- dst->pDrawable->width, dst->pDrawable->height));
- return true;
- }
-
- /* is the source picture only in cpu memory e.g. a shm pixmap? */
- return source_use_blt(sna, src);
-}
-
static void
gen3_align_vertex(struct sna *sna,
const struct sna_composite_op *op)
@@ -3530,7 +3484,6 @@ gen3_render_composite(struct sna *sna,
* 3D -> 2D context switch.
*/
if (mask == NULL &&
- try_blt(sna, dst, src, width, height) &&
sna_blt_composite(sna,
op, src, dst,
src_x, src_y,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 7e336f0..c625639 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1611,33 +1611,6 @@ gen5_composite_set_target(struct sna *sna,
}
static bool
-try_blt(struct sna *sna,
- PicturePtr dst, PicturePtr src,
- int width, int height)
-{
- if (sna->kgem.mode != KGEM_RENDER) {
- DBG(("%s: already performing BLT\n", __FUNCTION__));
- return true;
- }
-
- if (too_large(width, height)) {
- DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
- __FUNCTION__, width, height));
- return true;
- }
-
- if (too_large(dst->pDrawable->width, dst->pDrawable->height))
- return true;
-
- /* The blitter is much faster for solids */
- if (sna_picture_is_solid(src, NULL))
- return true;
-
- /* is the source picture only in cpu memory e.g. a shm pixmap? */
- return picture_is_cpu(sna, src);
-}
-
-static bool
is_gradient(PicturePtr picture, bool precise)
{
if (picture->pDrawable)
@@ -1868,7 +1841,6 @@ gen5_render_composite(struct sna *sna,
}
if (mask == NULL &&
- try_blt(sna, dst, src, width, height) &&
sna_blt_composite(sna, op,
src, dst,
src_x, src_y,
commit 3a05b1a4aa96f4d4484e7397b8e8d901819a3799
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Sep 25 10:52:17 2013 +0100
sna/gen6+: Fallback to BLT composite if fallback is forced
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 1f15091..b014e9e 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2267,7 +2267,13 @@ gen6_render_composite(struct sna *sna,
return true;
if (gen6_composite_fallback(sna, src, mask, dst))
- return false;
+ return (mask == NULL &&
+ sna_blt_composite(sna, op,
+ src, dst,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height,
+ tmp, true));
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 6f2e3ab..1b5e607 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2518,7 +2518,13 @@ gen7_render_composite(struct sna *sna,
return true;
if (gen7_composite_fallback(sna, src, mask, dst))
- return false;
+ return (mask == NULL &&
+ sna_blt_composite(sna, op,
+ src, dst,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height,
+ tmp, true));
if (need_tiling(sna, width, height))
return sna_tiling_composite(op, src, mask, dst,
commit 5dfe9217f21870c2b3563fb2337254db316eea72
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 24 13:48:28 2013 +0100
sna: Clear CPU damage when uploading partial images inplace
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 76a917c..7c03c61 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4051,20 +4051,26 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
if (priv == NULL)
return false;
- if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL)
+ if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL) {
+ DBG(("%s: no, no gpu damage\n", __FUNCTION__));
return false;
+ }
assert(priv->gpu_bo);
assert(priv->gpu_bo->proxy == NULL);
- if (priv->cow || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
+ if (priv->cow || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
+ DBG(("%s: no, target is idle\n", __FUNCTION__));
return false;
+ }
if (priv->cpu_damage &&
sna_damage_contains_box__no_reduce(priv->cpu_damage,
®ion->extents) &&
- !box_inplace(pixmap, ®ion->extents))
+ !box_inplace(pixmap, ®ion->extents)) {
+ DBG(("%s: no, damage on CPU and too small\n", __FUNCTION__));
return false;
+ }
src_bo = kgem_create_map(&sna->kgem, bits, stride * h, true);
if (src_bo == NULL)
@@ -4088,8 +4094,10 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
assert(src_bo->rq == NULL);
kgem_bo_destroy(&sna->kgem, src_bo);
- if (!ok)
+ if (!ok) {
+ DBG(("%s: copy failed!\n", __FUNCTION__));
return false;
+ }
if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
assert(!priv->clear);
@@ -4105,9 +4113,12 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
pixmap->drawable.width,
pixmap->drawable.height);
}
- if (DAMAGE_IS_ALL(priv->gpu_damage)) {
- list_del(&priv->flush_list);
+ if (DAMAGE_IS_ALL(priv->gpu_damage))
sna_damage_destroy(&priv->cpu_damage);
+ else
+ sna_damage_subtract(&priv->cpu_damage, region);
+ if (priv->cpu_damage == NULL) {
+ list_del(&priv->flush_list);
sna_pixmap_free_cpu(sna, priv, priv->cpu);
}
}
@@ -4213,12 +4224,15 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
} else {
sna_damage_add(&priv->gpu_damage, region);
sna_damage_reduce_all(&priv->gpu_damage,
- pixmap->drawable.width,
- pixmap->drawable.height);
+ pixmap->drawable.width,
+ pixmap->drawable.height);
}
- if (DAMAGE_IS_ALL(priv->gpu_damage)) {
- list_del(&priv->flush_list);
+ if (DAMAGE_IS_ALL(priv->gpu_damage))
sna_damage_destroy(&priv->cpu_damage);
+ else
+ sna_damage_subtract(&priv->cpu_damage, region);
+ if (priv->cpu_damage == NULL) {
+ list_del(&priv->flush_list);
sna_pixmap_free_cpu(sna, priv, priv->cpu);
}
}
commit 53b43673efed4d82b6dd498e9b76892e3e5b13e6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 24 13:44:59 2013 +0100
sna: Add some DBG for early flushes
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b0e0477..d46f967 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4571,8 +4571,10 @@ bool kgem_check_bo(struct kgem *kgem, ...)
if (bo->exec)
continue;
- if (needs_semaphore(kgem, bo))
+ if (needs_semaphore(kgem, bo)) {
+ DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
return false;
+ }
num_pages += num_pages(bo);
num_exec++;
@@ -4587,8 +4589,10 @@ bool kgem_check_bo(struct kgem *kgem, ...)
if (!num_pages)
return true;
- if (kgem_flush(kgem, flush))
+ if (kgem_flush(kgem, flush)) {
+ DBG(("%s: opportunistic flushing\n", __FUNCTION__));
return false;
+ }
if (kgem->aperture > kgem->aperture_low &&
kgem_ring_is_idle(kgem, kgem->ring)) {
@@ -4641,18 +4645,25 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
return true;
}
- if (needs_semaphore(kgem, bo))
+ if (needs_semaphore(kgem, bo)) {
+ DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
return false;
+ }
- if (kgem_flush(kgem, bo->flush))
+ if (kgem_flush(kgem, bo->flush)) {
+ DBG(("%s: opportunistic flushing\n", __FUNCTION__));
return false;
+ }
if (kgem->nexec >= KGEM_EXEC_SIZE(kgem) - 1)
return false;
if (kgem->aperture > kgem->aperture_low &&
- kgem_ring_is_idle(kgem, kgem->ring))
+ kgem_ring_is_idle(kgem, kgem->ring)) {
+ DBG(("%s: current aperture usage (%d) is greater than low water mark (%d)\n",
+ __FUNCTION__, kgem->aperture, kgem->aperture_low));
return false;
+ }
if (kgem->aperture + num_pages(bo) > kgem->aperture_high)
return false;
@@ -4703,8 +4714,10 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
continue;
}
- if (needs_semaphore(kgem, bo))
+ if (needs_semaphore(kgem, bo)) {
+ DBG(("%s: flushing for required semaphore\n", __FUNCTION__));
return false;
+ }
assert_tiling(kgem, bo);
num_pages += num_pages(bo);
@@ -4731,12 +4744,17 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
}
if (num_pages) {
- if (kgem_flush(kgem, flush))
+ if (kgem_flush(kgem, flush)) {
+ DBG(("%s: opportunistic flushing\n", __FUNCTION__));
return false;
+ }
if (kgem->aperture > kgem->aperture_low &&
- kgem_ring_is_idle(kgem, kgem->ring))
+ kgem_ring_is_idle(kgem, kgem->ring)) {
+ DBG(("%s: current aperture usage (%d) is greater than low water mark (%d)\n",
+ __FUNCTION__, kgem->aperture, kgem->aperture_low));
return false;
+ }
if (num_pages + kgem->aperture > kgem->aperture_high)
return false;
commit ad0390068832ad4727371902fe41a85a53de1894
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 24 10:00:03 2013 +0100
sna: Separate out copy preferrence from operating in place decision
The two decision trees are no longer identical.
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 fb8a228..76a917c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3195,6 +3195,11 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
if (priv->cpu && (flags & (FORCE_GPU | IGNORE_CPU)) == 0)
flags &= ~PREFER_GPU;
+ if ((flags & (PREFER_GPU | IGNORE_CPU)) == IGNORE_CPU) {
+ if (box_inplace(pixmap, box))
+ flags |= PREFER_GPU;
+ }
+
DBG(("%s: flush=%d, shm=%d, cpu=%d => flags=%x\n",
__FUNCTION__, priv->flush, priv->shm, priv->cpu, flags));
@@ -4690,6 +4695,9 @@ source_contains_region(struct sna_damage *damage,
if (DAMAGE_IS_ALL(damage))
return true;
+ if (damage == NULL)
+ return false;
+
box = region->extents;
box.x1 += dx;
box.x2 += dx;
@@ -4954,39 +4962,46 @@ sna_pixmap_is_gpu(PixmapPtr pixmap)
}
static int
-source_prefer_gpu(struct sna *sna, struct sna_pixmap *priv,
- RegionRec *region, int16_t dx, int16_t dy)
+copy_prefer_gpu(struct sna *sna,
+ struct sna_pixmap *dst_priv,
+ struct sna_pixmap *src_priv,
+ RegionRec *region,
+ int16_t dx, int16_t dy)
{
- if (priv == NULL) {
+ assert(dst_priv);
+
+ if (wedged(sna) && !dst_priv->pinned)
+ return 0;
+
+ if (src_priv == NULL) {
DBG(("%s: source unattached, use cpu\n", __FUNCTION__));
return 0;
}
- if (priv->clear) {
+ if (src_priv->clear) {
DBG(("%s: source is clear, don't force use of GPU\n", __FUNCTION__));
return 0;
}
- if (priv->gpu_damage &&
- (priv->cpu_damage == NULL ||
- !source_contains_region(priv->cpu_damage, region, dx, dy))) {
+ if (src_priv->gpu_damage &&
+ !source_contains_region(src_priv->cpu_damage, region, dx, dy)) {
DBG(("%s: source has gpu damage, force gpu? %d\n",
- __FUNCTION__, priv->cpu_damage == NULL));
- assert(priv->gpu_bo);
- return priv->cpu_damage ? PREFER_GPU : PREFER_GPU | FORCE_GPU;
+ __FUNCTION__, src_priv->cpu_damage == NULL));
+ assert(src_priv->gpu_bo);
+ return src_priv->cpu_damage ? PREFER_GPU : PREFER_GPU | FORCE_GPU;
}
- if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) {
+ if (src_priv->cpu_bo && kgem_bo_is_busy(src_priv->cpu_bo)) {
DBG(("%s: source has busy CPU bo, force gpu\n", __FUNCTION__));
return PREFER_GPU | FORCE_GPU;
}
- if (DAMAGE_IS_ALL(priv->cpu_damage))
- return priv->cpu_bo && kgem_is_idle(&sna->kgem);
+ if (source_contains_region(src_priv->cpu_damage, region, dx, dy))
+ return src_priv->cpu_bo && kgem_is_idle(&sna->kgem);
DBG(("%s: source has GPU bo? %d\n",
- __FUNCTION__, priv->gpu_bo != NULL));
- return priv->gpu_bo != NULL;
+ __FUNCTION__, src_priv->gpu_bo != NULL));
+ return src_priv->gpu_bo != NULL;
}
static bool use_shm_bo(struct sna *sna,
@@ -5161,6 +5176,22 @@ sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu,
return true;
}
+static void discard_cpu_damage(struct sna *sna, struct sna_pixmap *priv)
+{
+ DBG(("%s: discarding existing CPU damage\n", __FUNCTION__));
+ if (priv->gpu_bo && priv->gpu_bo->proxy) {
+ assert(priv->gpu_damage == NULL);
+ assert(!priv->pinned);
+ kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
+ priv->gpu_bo = NULL;
+ }
+ sna_damage_destroy(&priv->cpu_damage);
+ list_del(&priv->flush_list);
+
+ sna_pixmap_free_cpu(sna, priv, priv->cpu);
+ priv->cpu = false;
+}
+
static void
sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
RegionPtr region, int dx, int dy,
@@ -5173,7 +5204,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
struct sna *sna = to_sna_from_pixmap(src_pixmap);
struct sna_damage **damage;
struct kgem_bo *bo;
- unsigned hint;
int16_t src_dx, src_dy;
int16_t dst_dx, dst_dy;
BoxPtr box = RegionRects(region);
@@ -5233,26 +5263,6 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
if (dst_priv == NULL)
goto fallback;
- hint = source_prefer_gpu(sna, src_priv, region, src_dx, src_dy) ?:
- region_inplace(sna, dst_pixmap, region,
- dst_priv, alu_overwrites(alu) ? MOVE_WRITE : MOVE_READ | MOVE_WRITE);
- if (dst_priv->cpu_damage && alu_overwrites(alu)) {
- DBG(("%s: overwritting CPU damage\n", __FUNCTION__));
- if (region_subsumes_damage(region, dst_priv->cpu_damage)) {
- DBG(("%s: discarding existing CPU damage\n", __FUNCTION__));
- if (dst_priv->gpu_bo && dst_priv->gpu_bo->proxy) {
- assert(!dst_priv->pinned);
- kgem_bo_destroy(&sna->kgem, dst_priv->gpu_bo);
- dst_priv->gpu_bo = NULL;
- }
- sna_damage_destroy(&dst_priv->cpu_damage);
- list_del(&dst_priv->flush_list);
- dst_priv->cpu = false;
- }
- }
- if (region->data == NULL && alu_overwrites(alu))
- hint |= IGNORE_CPU;
-
/* XXX hack for firefox -- subsequent uses of src will be corrupt! */
if (src_priv &&
COW(src_priv->cow) == COW(dst_priv->cow) &&
@@ -5262,9 +5272,24 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
assert(src_priv->cpu_damage == NULL);
bo = dst_priv->gpu_bo;
damage = NULL;
- } else
+ } else {
+ unsigned hint = copy_prefer_gpu(sna, dst_priv, src_priv, region, src_dx, src_dy);
+ if (replaces) {
+ discard_cpu_damage(sna, dst_priv);
+ hint |= REPLACES | IGNORE_CPU;
+ } else if (alu_overwrites(alu)) {
+ if (region->data == NULL)
+ hint |= IGNORE_CPU;
+ if (dst_priv->cpu_damage &&
+ region_subsumes_damage(region,
+ dst_priv->cpu_damage)) {
+ discard_cpu_damage(sna, dst_priv);
+ hint |= IGNORE_CPU;
+ }
+ }
bo = sna_drawable_use_bo(&dst_pixmap->drawable, hint,
®ion->extents, &damage);
+ }
if (bo) {
if (src_priv && src_priv->clear) {
DBG(("%s: applying src clear [%08x] to dst\n",
@@ -12909,22 +12934,18 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
RegionTranslate(®ion, dx, dy);
}
- if (priv->cpu_damage && (flags & 2) == 0) {
- if (region_subsumes_damage(®ion, priv->cpu_damage)) {
- DBG(("%s: discarding existing CPU damage\n", __FUNCTION__));
- if (priv->gpu_bo && priv->gpu_bo->proxy) {
- assert(priv->gpu_damage == NULL);
- assert(!priv->pinned);
- kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
- priv->gpu_bo = NULL;
- }
- sna_damage_destroy(&priv->cpu_damage);
- list_del(&priv->flush_list);
+ if (region_subsumes_drawable(®ion, &pixmap->drawable)) {
+ discard_cpu_damage(sna, priv);
+ hint |= IGNORE_CPU | REPLACES;
+ } else {
+ if ((flags & 2) == 0)
+ hint |= IGNORE_CPU;
+ if (priv->cpu_damage &&
+ region_subsumes_damage(®ion, priv->cpu_damage)) {
+ discard_cpu_damage(sna, priv);
+ hint |= IGNORE_CPU;
}
- hint |= IGNORE_CPU;
}
- if (region_subsumes_drawable(®ion, &pixmap->drawable))
- hint |= REPLACES;
if (priv->cpu_damage == NULL) {
if (priv->gpu_bo &&
(hint & REPLACES || box_inplace(pixmap, ®ion.extents))) {
More information about the xorg-commit
mailing list