xf86-video-intel: 2 commits - src/sna/kgem.c src/sna/sna_accel.c
Chris Wilson
ickle at kemper.freedesktop.org
Tue Sep 4 06:17:22 PDT 2012
src/sna/kgem.c | 2
src/sna/sna_accel.c | 131 +++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 115 insertions(+), 18 deletions(-)
New commits:
commit 68d207588a177afa4e999260bfddb4d6dba1029b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 4 13:20:21 2012 +0100
sna: Improve handling of output offloading
In particular, don't forget to flush when we only have offload slaves
and no native pixmaps.
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 b08e701..a554655 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -937,6 +937,7 @@ sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle)
return FALSE;
assert(priv->gpu_bo);
+ assert(priv->stride);
/* XXX negotiate format and stride restrictions */
if (priv->gpu_bo->tiling &&
@@ -13607,6 +13608,20 @@ static void sna_accel_disarm_timer(struct sna *sna, int id)
sna->timer_active &= ~(1<<id);
}
+static bool has_offload_slaves(struct sna *sna)
+{
+#if HAS_PIXMAP_SHARING
+ ScreenPtr screen = sna->scrn->pScreen;
+ PixmapDirtyUpdatePtr dirty;
+
+ xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
+ if (RegionNotEmpty(DamageRegion(dirty->damage)))
+ return true;
+ }
+#endif
+ return false;
+}
+
static bool has_shadow(struct sna *sna)
{
DamagePtr damage = sna->mode.shadow_damage;
@@ -13625,13 +13640,16 @@ static bool has_shadow(struct sna *sna)
static bool start_flush(struct sna *sna, struct sna_pixmap *scanout)
{
- DBG(("%s: scanout=%d shadow?=%d, (cpu?=%d || gpu?=%d))\n",
+ DBG(("%s: scanout=%d shadow?=%d, slaves?=%d, (cpu?=%d || gpu?=%d))\n",
__FUNCTION__,
scanout && scanout->gpu_bo ? scanout->gpu_bo->handle : 0,
- has_shadow(sna),
+ has_shadow(sna), has_offload_slaves(sna),
scanout && scanout->cpu_damage != NULL,
scanout && scanout->gpu_bo && scanout->gpu_bo->exec != NULL));
+ if (has_offload_slaves(sna))
+ return true;
+
if (has_shadow(sna))
return true;
@@ -13643,13 +13661,16 @@ static bool start_flush(struct sna *sna, struct sna_pixmap *scanout)
static bool stop_flush(struct sna *sna, struct sna_pixmap *scanout)
{
- DBG(("%s: scanout=%d shadow?=%d, (cpu?=%d || gpu?=%d))\n",
+ DBG(("%s: scanout=%d shadow?=%d, slaves?=%d, (cpu?=%d || gpu?=%d))\n",
__FUNCTION__,
scanout && scanout->gpu_bo ? scanout->gpu_bo->handle : 0,
- has_shadow(sna),
+ has_shadow(sna), has_offload_slaves(sna),
scanout && scanout->cpu_damage != NULL,
scanout && scanout->gpu_bo && scanout->gpu_bo->rq != NULL));
+ if (has_offload_slaves(sna))
+ return true;
+
if (has_shadow(sna))
return true;
@@ -13662,9 +13683,10 @@ static bool stop_flush(struct sna *sna, struct sna_pixmap *scanout)
static bool sna_accel_do_flush(struct sna *sna)
{
struct sna_pixmap *priv;
+ int interval;
priv = sna_accel_scanout(sna);
- if (priv == NULL && !sna->mode.shadow_active) {
+ if (priv == NULL && !sna->mode.shadow_active && !has_offload_slaves(sna)) {
DBG(("%s -- no scanout attached\n", __FUNCTION__));
sna_accel_disarm_timer(sna, FLUSH_TIMER);
return false;
@@ -13673,14 +13695,14 @@ static bool sna_accel_do_flush(struct sna *sna)
if (sna->flags & SNA_NO_DELAYED_FLUSH)
return true;
+ interval = sna->vblank_interval ?: 20;
if (sna->timer_active & (1<<(FLUSH_TIMER))) {
int32_t delta = sna->timer_expire[FLUSH_TIMER] - TIME;
DBG(("%s: flush timer active: delta=%d\n",
__FUNCTION__, delta));
if (delta <= 3) {
DBG(("%s (time=%ld), triggered\n", __FUNCTION__, (long)TIME));
- sna->timer_expire[FLUSH_TIMER] =
- TIME + sna->vblank_interval;
+ sna->timer_expire[FLUSH_TIMER] = TIME + interval;
return true;
}
} else {
@@ -13690,8 +13712,7 @@ static bool sna_accel_do_flush(struct sna *sna)
kgem_bo_flush(&sna->kgem, priv->gpu_bo);
} else {
sna->timer_active |= 1 << FLUSH_TIMER;
- sna->timer_expire[FLUSH_TIMER] =
- TIME + sna->vblank_interval / 2;
+ sna->timer_expire[FLUSH_TIMER] = TIME + interval / 2;
DBG(("%s (time=%ld), starting\n", __FUNCTION__, (long)TIME));
}
}
@@ -13800,19 +13821,95 @@ static void sna_accel_post_damage(struct sna *sna)
PixmapDirtyUpdatePtr dirty;
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
- RegionRec pixregion;
+ RegionRec region, *damage;
+ PixmapPtr src, dst;
+ BoxPtr box;
+ int n;
- if (!RegionNotEmpty(DamageRegion(dirty->damage)))
+ damage = DamageRegion(dirty->damage);
+ if (!RegionNotEmpty(damage))
continue;
- PixmapRegionInit(&pixregion,
- dirty->slave_dst->master_pixmap);
- PixmapSyncDirtyHelper(dirty, &pixregion);
+ src = dirty->src;
+ dst = dirty->slave_dst->master_pixmap;
+
+ region.extents.x1 = dirty->x;
+ region.extents.x2 = dirty->x + dst->drawable.width;
+ region.extents.y1 = dirty->y;
+ region.extents.y2 = dirty->y + dst->drawable.height;
+ region.data = NULL;
+
+ DBG(("%s: pushing damage ((%d, %d), (%d, %d))x%d to slave pixmap=%ld, ((%d, %d), (%d, %d))\n", __FUNCTION__,
+ damage->extents.x1, damage->extents.y1,
+ damage->extents.x2, damage->extents.y2,
+ RegionNumRects(damage),
+ dst->drawable.serialNumber,
+ region.extents.x1, region.extents.y1,
+ region.extents.x2, region.extents.y2));
+
+ RegionIntersect(®ion, ®ion, damage);
+
+ box = REGION_RECTS(®ion);
+ n = REGION_NUM_RECTS(®ion);
+ if (wedged(sna)) {
+fallback:
+ if (!sna_pixmap_move_to_cpu(src, MOVE_READ))
+ goto skip;
+
+ if (!sna_pixmap_move_to_cpu(dst, MOVE_READ | MOVE_WRITE | MOVE_INPLACE_HINT))
+ goto skip;
+
+ assert(src->drawable.bitsPerPixel == dst->drawable.bitsPerPixel);
+ do {
+ DBG(("%s: copy box (%d, %d)->(%d, %d)x(%d, %d)\n",
+ __FUNCTION__,
+ box->x1, box->y1,
+ box->x1 - dirty->x, box->y1 - dirty->y,
+ box->x2 - box->x1, box->y2 - box->y1));
+
+ assert(box->x2 > box->x1);
+ assert(box->y2 > box->y1);
+
+ assert(box->x1 >= 0);
+ assert(box->y1 >= 0);
+ assert(box->x2 <= src->drawable.width);
+ assert(box->y2 <= src->drawable.height);
+
+ assert(box->x1 - dirty->x >= 0);
+ assert(box->y1 - dirty->y >= 0);
+ assert(box->x2 - dirty->x <= src->drawable.width);
+ assert(box->y2 - dirty->y <= src->drawable.height);
+
+ memcpy_blt(src->devPrivate.ptr,
+ dst->devPrivate.ptr,
+ src->drawable.bitsPerPixel,
+ src->devKind, dst->devKind,
+ box->x1, box->y1,
+ box->x1 - dirty->x,
+ box->y1 - dirty->y,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
+ box++;
+ } while (--n);
+ } else {
+ if (!sna_pixmap_move_to_gpu(src, MOVE_READ | __MOVE_FORCE))
+ goto fallback;
- DamageRegionAppend(&dirty->slave_dst->drawable,
- &pixregion);
- RegionUninit(&pixregion);
+ if (!sna_pixmap_move_to_gpu(dst, MOVE_READ | MOVE_WRITE | __MOVE_FORCE))
+ goto fallback;
+ if (!sna->render.copy_boxes(sna, GXcopy,
+ src, sna_pixmap_get_bo(src), 0, 0,
+ dst, sna_pixmap_get_bo(dst), -dirty->x, -dirty->y,
+ box, n, COPY_LAST))
+ goto fallback;
+ }
+
+ RegionTranslate(®ion, -dirty->x, -dirty->y);
+ DamageRegionAppend(&dirty->slave_dst->drawable, ®ion);
+
+skip:
+ RegionUninit(®ion);
DamageEmpty(dirty->damage);
}
#endif
commit 8cf7ac776b9b47dabd5ab141e5a5385c44d3f309
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Sep 4 13:55:34 2012 +0100
sna: Fix a typo in an error message
s/achieve/retrieve/ otherwise it is nonsense.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index ae0a604..229a799 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -255,7 +255,7 @@ retry_gtt:
VG_CLEAR(mmap_arg);
mmap_arg.handle = bo->handle;
if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg)) {
- ErrorF("%s: failed to achieve GTT offset for handle=%d: %d\n",
+ ErrorF("%s: failed to retrieve GTT offset for handle=%d: %d\n",
__FUNCTION__, bo->handle, errno);
(void)__kgem_throttle_retire(kgem, 0);
if (kgem_expire_cache(kgem))
More information about the xorg-commit
mailing list