diff options
-rw-r--r-- | src/sna/gen2_render.c | 8 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 8 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 19 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 19 | ||||
-rw-r--r-- | src/sna/kgem.c | 17 | ||||
-rw-r--r-- | src/sna/kgem.h | 6 | ||||
-rw-r--r-- | src/sna/sna_render.c | 8 |
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; } |