summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sna/gen2_render.c8
-rw-r--r--src/sna/gen5_render.c8
-rw-r--r--src/sna/gen6_render.c19
-rw-r--r--src/sna/gen7_render.c19
-rw-r--r--src/sna/kgem.c17
-rw-r--r--src/sna/kgem.h6
-rw-r--r--src/sna/sna_render.c8
7 files changed, 69 insertions, 16 deletions
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 9e51cb70..d2f6fe74 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 2894c58d..aaf7e495 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 84e79028..bfbcfd8c 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 99296fb1..08ba6a09 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 1cf79577..825caa76 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 583bafca..d085a2f0 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 8373890c..0d4d7068 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;
}