diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-10-24 09:12:49 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-10-29 16:55:58 +0000 |
commit | 9d48d2817927bc2532953f09b6be2002c2086e1f (patch) | |
tree | 5b5f3e03525dea6662f32b6f3159579cae5abf32 | |
parent | 61436c2fabe117b85404eecb06158ba0a63a7741 (diff) |
sna: Reuse the same fence until retired
In order to reduce the number of breadcrumbs the kernel must emit to
track our batches, reuse the last query until it has retired.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 36 | ||||
-rw-r--r-- | src/sna/kgem.h | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 6 |
3 files changed, 38 insertions, 5 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 0eef0360..86810180 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -2523,6 +2523,9 @@ static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq) __FUNCTION__, rq->bo->handle)); assert(RQ(rq->bo->rq) == rq); + if (rq == kgem->fence[rq->ring]) + kgem->fence[rq->ring] = NULL; + while (!list_is_empty(&rq->buffers)) { struct kgem_bo *bo; @@ -2653,21 +2656,50 @@ bool __kgem_ring_is_idle(struct kgem *kgem, int ring) assert(ring < ARRAY_SIZE(kgem->requests)); assert(!list_is_empty(&kgem->requests[ring])); + rq = kgem->fence[ring]; + if (rq) { + struct kgem_request *tmp; + + if (__kgem_busy(kgem, rq->bo->handle)) { + DBG(("%s: last fence handle=%d still busy\n", + __FUNCTION__, rq->bo->handle)); + return false; + } + + do { + tmp = list_first_entry(&kgem->requests[ring], + struct kgem_request, + list); + assert(tmp->ring == ring); + __kgem_retire_rq(kgem, tmp); + } while (tmp != rq); + + assert(kgem->fence[ring] == NULL); + if (list_is_empty(&kgem->requests[ring])) + return true; + } + rq = list_last_entry(&kgem->requests[ring], struct kgem_request, list); assert(rq->ring == ring); if (__kgem_busy(kgem, rq->bo->handle)) { DBG(("%s: last requests handle=%d still busy\n", __FUNCTION__, rq->bo->handle)); + kgem->fence[ring] = rq; return false; } DBG(("%s: ring=%d idle (handle=%d)\n", __FUNCTION__, ring, rq->bo->handle)); - kgem_retire__requests_ring(kgem, ring); + while (!list_is_empty(&kgem->requests[ring])) { + rq = list_first_entry(&kgem->requests[ring], + struct kgem_request, + list); + assert(rq->ring == ring); + __kgem_retire_rq(kgem, rq); + } - assert(list_is_empty(&kgem->requests[ring])); return true; } diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 4a74f2ef..bea518f8 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -155,6 +155,7 @@ struct kgem { struct list batch_buffers, active_buffers; struct list requests[2]; + struct kgem_request *fence[2]; struct kgem_request *next_request; struct kgem_request static_request; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index b2fe6d4a..d2142604 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1398,9 +1398,9 @@ void sna_add_flush_pixmap(struct sna *sna, assert(priv->gpu_damage == NULL || priv->gpu_bo); list_move(&priv->flush_list, &sna->flush_pixmaps); - if (bo->exec == NULL && kgem_is_idle(&sna->kgem)) { - DBG(("%s: new flush bo, flushin before\n", __FUNCTION__)); - kgem_submit(&sna->kgem); + if (bo->exec == NULL && sna->kgem.nbatch && kgem_is_idle(&sna->kgem)) { + DBG(("%s: new flush bo, flushing before\n", __FUNCTION__)); + _kgem_submit(&sna->kgem); } } |