summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-10-24 09:12:49 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-10-29 16:55:58 +0000
commit9d48d2817927bc2532953f09b6be2002c2086e1f (patch)
tree5b5f3e03525dea6662f32b6f3159579cae5abf32
parent61436c2fabe117b85404eecb06158ba0a63a7741 (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.c36
-rw-r--r--src/sna/kgem.h1
-rw-r--r--src/sna/sna_accel.c6
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);
}
}