xf86-video-intel: 3 commits - src/sna/gen2_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_render.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Aug 24 06:06:02 PDT 2012


 src/sna/gen2_render.c |    8 ++++++++
 src/sna/gen5_render.c |    8 ++++++++
 src/sna/gen6_render.c |   21 +++++++++++++++------
 src/sna/gen7_render.c |   19 ++++++++++++++-----
 src/sna/kgem.c        |   17 +++++++++++++++--
 src/sna/kgem.h        |    6 ++----
 src/sna/sna_accel.c   |    6 ++++--
 src/sna/sna_render.c  |    8 ++++++++
 8 files changed, 74 insertions(+), 19 deletions(-)

New commits:
commit 454cc8453af1852758c3396dbe303c13c5c1be27
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Aug 24 08:48:12 2012 +0100

    sna: Submit the partial batch before throttling
    
    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 9bc8c48..fd9728c 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -13691,8 +13691,10 @@ static void sna_accel_throttle(struct sna *sna)
 {
 	DBG(("%s (time=%ld)\n", __FUNCTION__, (long)TIME));
 
-	if (sna->kgem.need_throttle)
+	if (sna->kgem.need_throttle) {
+		kgem_submit(&sna->kgem);
 		kgem_throttle(&sna->kgem);
+	}
 
 	if (!sna->kgem.need_retire)
 		sna_accel_disarm_timer(sna, THROTTLE_TIMER);
commit 0e1e83ed4952f620e9422e58f955a5aea406e300
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Aug 24 00:59:31 2012 +0100

    sna: Allow the batch to be flushed if the GPU is idle upon a context switch
    
    Submit early, submit often in order to keep the GPU busy. As always we
    trade off CPU overhead versus concurrency.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 9e51cb7..d2f6fe7 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -3124,8 +3124,16 @@ gen2_render_context_switch(struct kgem *kgem,
 {
 	struct sna *sna = container_of(kgem, struct sna, kgem);
 
+	if (!kgem->mode)
+		return;
+
 	/* Reload BLT registers following a lost context */
 	sna->blt_state.fill_bo = 0;
+
+	if (kgem_is_idle(kgem)) {
+		DBG(("%s: GPU idle, flushing\n", __FUNCTION__));
+		_kgem_submit(kgem);
+	}
 }
 
 bool gen2_render_init(struct sna *sna)
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 2894c58..aaf7e49 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -3509,6 +3509,9 @@ static void
 gen5_render_context_switch(struct kgem *kgem,
 			   int new_mode)
 {
+	if (!kgem->mode)
+		return;
+
 	/* Ironlake has a limitation that a 3D or Media command can't
 	 * be the first command after a BLT, unless it's
 	 * non-pipelined.
@@ -3522,6 +3525,11 @@ gen5_render_context_switch(struct kgem *kgem,
 		     __FUNCTION__));
 		sna->render_state.gen5.drawrect_limit = -1;
 	}
+
+	if (kgem_is_idle(kgem)) {
+		DBG(("%s: GPU idle, flushing\n", __FUNCTION__));
+		_kgem_submit(kgem);
+	}
 }
 
 static void
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 84e7902..bfbcfd8 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2366,9 +2366,18 @@ static bool prefer_blt_ring(struct sna *sna)
 	return sna->kgem.ring != KGEM_RENDER;
 }
 
-static bool can_switch_rings(struct sna *sna)
+static bool can_switch_to_blt(struct sna *sna)
 {
-	return sna->kgem.mode == KGEM_NONE && sna->kgem.has_semaphores && !NO_RING_SWITCH;
+	if (sna->kgem.ring == KGEM_BLT)
+		return true;
+
+	if (NO_RING_SWITCH)
+		return false;
+
+	if (!sna->kgem.has_semaphores)
+		return false;
+
+	return sna->kgem.mode == KGEM_NONE || kgem_is_idle(&sna->kgem);
 }
 
 static inline bool untiled_tlb_miss(struct kgem_bo *bo)
@@ -2397,7 +2406,7 @@ try_blt(struct sna *sna,
 		return true;
 	}
 
-	if (can_switch_rings(sna) && sna_picture_is_solid(src, NULL))
+	if (can_switch_to_blt(sna) && sna_picture_is_solid(src, NULL))
 		return true;
 
 	return false;
@@ -3328,7 +3337,7 @@ fallback_blt:
 		if (too_large(extents.x2-extents.x1, extents.y2-extents.y1))
 			goto fallback_blt;
 
-		if ((flags & COPY_LAST || can_switch_rings(sna)) &&
+		if ((flags & COPY_LAST || can_switch_to_blt(sna)) &&
 		    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 		    sna_blt_copy_boxes(sna, alu,
 				       src_bo, src_dx, src_dy,
@@ -3646,7 +3655,7 @@ static inline bool prefer_blt_fill(struct sna *sna,
 	if (PREFER_RENDER)
 		return PREFER_RENDER < 0;
 
-	return (can_switch_rings(sna) ||
+	return (can_switch_to_blt(sna) ||
 		prefer_blt_ring(sna) ||
 		untiled_tlb_miss(bo));
 }
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 99296fb..08ba6a0 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2455,9 +2455,18 @@ gen7_composite_set_target(struct sna *sna, struct sna_composite_op *op, PictureP
 	return true;
 }
 
-inline static bool can_switch_rings(struct sna *sna)
+inline static bool can_switch_to_blt(struct sna *sna)
 {
-	return sna->kgem.mode == KGEM_NONE && sna->kgem.has_semaphores && !NO_RING_SWITCH;
+	if (sna->kgem.ring == KGEM_BLT)
+		return true;
+
+	if (NO_RING_SWITCH)
+		return false;
+
+	if (!sna->kgem.has_semaphores)
+		return false;
+
+	return sna->kgem.mode == KGEM_NONE || kgem_is_idle(&sna->kgem);
 }
 
 static inline bool untiled_tlb_miss(struct kgem_bo *bo)
@@ -2472,7 +2481,7 @@ static bool prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
 
 inline static bool prefer_blt_ring(struct sna *sna)
 {
-	return sna->kgem.ring != KGEM_RENDER || can_switch_rings(sna);
+	return sna->kgem.ring != KGEM_RENDER || can_switch_to_blt(sna);
 }
 
 static bool
@@ -2491,7 +2500,7 @@ try_blt(struct sna *sna,
 		return true;
 	}
 
-	if (can_switch_rings(sna)) {
+	if (can_switch_to_blt(sna)) {
 		if (sna_picture_is_solid(src, NULL))
 			return true;
 
@@ -3416,7 +3425,7 @@ fallback_blt:
 		if (too_large(extents.x2-extents.x1, extents.y2-extents.y1))
 			goto fallback_blt;
 
-		if ((flags & COPY_LAST || can_switch_rings(sna)) &&
+		if ((flags & COPY_LAST || can_switch_to_blt(sna)) &&
 		    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 		    sna_blt_copy_boxes(sna, alu,
 				       src_bo, src_dx, src_dy,
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 1cf7957..825caa7 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1158,8 +1158,6 @@ void _kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
 
 static uint32_t kgem_end_batch(struct kgem *kgem)
 {
-	kgem->context_switch(kgem, KGEM_NONE);
-
 	kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
 	if (kgem->nbatch & 1)
 		kgem->batch[kgem->nbatch++] = MI_NOOP;
@@ -1758,6 +1756,21 @@ bool kgem_retire(struct kgem *kgem)
 	return retired;
 }
 
+bool __kgem_is_idle(struct kgem *kgem)
+{
+	struct kgem_request *rq;
+
+	assert(!list_is_empty(&kgem->requests));
+
+	rq = list_last_entry(&kgem->requests, struct kgem_request, list);
+	if (kgem_busy(kgem, rq->bo->handle))
+		return false;
+
+	kgem_retire__requests(kgem);
+	assert(list_is_empty(&kgem->requests));
+	return true;
+}
+
 static void kgem_commit(struct kgem *kgem)
 {
 	struct kgem_request *rq = kgem->next_request;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 583bafc..d085a2f 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -258,15 +258,13 @@ void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset);
 
 void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo);
 bool kgem_retire(struct kgem *kgem);
+bool __kgem_is_idle(struct kgem *kgem);
 static inline bool kgem_is_idle(struct kgem *kgem)
 {
 	if (list_is_empty(&kgem->requests))
 		return true;
 
-	if (!kgem_retire(kgem))
-		return false;
-
-	return list_is_empty(&kgem->requests);
+	return __kgem_is_idle(kgem);
 }
 struct kgem_bo *kgem_get_last_request(struct kgem *kgem);
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 8373890..0d4d706 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -246,6 +246,14 @@ static void
 no_render_context_switch(struct kgem *kgem,
 			 int new_mode)
 {
+	if (!kgem->mode)
+		return;
+
+	if (kgem_is_idle(kgem)) {
+		DBG(("%s: GPU idle, flushing\n", __FUNCTION__));
+		_kgem_submit(kgem);
+	}
+
 	(void)kgem;
 	(void)new_mode;
 }
commit 5059db0697c5516f1538f7062937664baf7b1c2e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Aug 24 00:21:07 2012 +0100

    sna: Correct a pair of DBG messages
    
    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 257dbc8..84e7902 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -1235,7 +1235,7 @@ gen6_bind_bo(struct sna *sna,
 	if (offset) {
 		DBG(("[%x]  bo(handle=%d), format=%d, reuse %s binding\n",
 		     offset, bo->handle, format,
-		     domains & 0xffff ? "render" : "sampler"));
+		     is_dst ? "render" : "sampler"));
 		if (is_dst)
 			kgem_bo_mark_dirty(bo);
 		return offset * sizeof(uint32_t);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index dfb1491..9bc8c48 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -13427,7 +13427,7 @@ sna_accel_flush_callback(CallbackListPtr *list,
 	 * and doesn't appear to mitigate the performance loss.
 	 */
 	DBG(("%s: flush?=%d, dirty?=%d\n", __FUNCTION__,
-	     sna->kgem.flush, list_is_empty(&sna->flush_pixmap)));
+	     sna->kgem.flush, !list_is_empty(&sna->flush_pixmaps)));
 
 	/* flush any pending damage from shadow copies to tfp clients */
 	while (!list_is_empty(&sna->flush_pixmaps)) {


More information about the xorg-commit mailing list