Commit 95ea0564 authored by Chris Wilson's avatar Chris Wilson 🤔
Browse files

sna: Rebalance prefer_blt to weight I915_TILING_Y higher



Mixing I915_TILING_Y and the blitter is painfully slow, so we need to
take use of I915_TILING_Y into more prominent consideration and even
force a ring switch in case it is being used.
Signed-off-by: Chris Wilson's avatarChris Wilson <chris@chris-wilson.co.uk>
parent bd585f62
......@@ -43,15 +43,15 @@ inline static bool can_switch_to_blt(struct sna *sna,
struct kgem_bo *bo,
unsigned flags)
{
if (sna->kgem.ring != KGEM_RENDER)
if (bo && bo->tiling == I915_TILING_Y)
return false;
if (PREFER_RENDER < 0 && sna->kgem.ring != KGEM_RENDER)
return true;
if (bo && RQ_IS_BLT(bo->rq))
return true;
if (bo && bo->tiling == I915_TILING_Y)
return false;
if (bo && !kgem_bo_can_blt(&sna->kgem, bo))
return false;
......@@ -87,41 +87,45 @@ static int prefer_blt_bo(struct sna *sna,
if (PREFER_RENDER)
return PREFER_RENDER < 0;
if (dst->rq)
return RQ_IS_BLT(dst->rq);
if (sna->flags & SNA_POWERSAVE)
return true;
if (dst->tiling == I915_TILING_Y)
return false;
if (src) {
if (sna->render_state.gt > 1)
return false;
if (src->rq)
return RQ_IS_BLT(src->rq);
if (src->tiling == I915_TILING_Y)
return false;
if (src->rq)
return RQ_IS_BLT(src->rq);
} else {
if (sna->render_state.gt > 2)
return false;
}
if (dst->rq)
return RQ_IS_BLT(dst->rq);
if (sna->flags & SNA_POWERSAVE)
return true;
if (sna->render_state.gt < 2)
return true;
return dst->tiling == I915_TILING_NONE || is_uncached(sna, dst);
}
inline static bool force_blt_ring(struct sna *sna, struct kgem_bo *bo)
inline static bool
force_blt_ring(struct sna *sna, struct kgem_bo *dst, struct kgem_bo *src)
{
if (sna->kgem.mode == KGEM_RENDER)
if (sna->kgem.ring != KGEM_BLT)
return false;
if (NO_RING_SWITCH(sna))
return sna->kgem.ring == KGEM_BLT;
return sna->kgem.mode == KGEM_BLT;
if (bo->tiling == I915_TILING_Y)
if (kgem_bo_is_render(dst) || (src && kgem_bo_is_render(src)))
return false;
if (sna->flags & SNA_POWERSAVE)
......@@ -139,10 +143,10 @@ prefer_blt_ring(struct sna *sna, struct kgem_bo *bo, unsigned flags)
if (PREFER_RENDER)
return PREFER_RENDER < 0;
assert(!force_blt_ring(sna, bo));
assert(!force_blt_ring(sna, bo, NULL));
assert(!kgem_bo_is_render(bo) || NO_RING_SWITCH(sna));
if (kgem_bo_is_blt(bo))
if (!sna->kgem.has_semaphores && kgem_bo_is_blt(bo))
return true;
return can_switch_to_blt(sna, bo, flags);
......@@ -179,7 +183,7 @@ prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
untiled_tlb_miss(tmp->src.bo))
return true;
if (force_blt_ring(sna, tmp->dst.bo))
if (force_blt_ring(sna, tmp->dst.bo, tmp->src.bo))
return true;
if (prefer_render_ring(sna, tmp->dst.bo))
......@@ -200,7 +204,7 @@ prefer_blt_fill(struct sna *sna, struct kgem_bo *bo, unsigned flags)
if (untiled_tlb_miss(bo))
return true;
if (force_blt_ring(sna, bo))
if (force_blt_ring(sna, bo, NULL))
return true;
if ((flags & (FILL_POINTS | FILL_SPANS)) == 0) {
......
......@@ -2761,7 +2761,7 @@ static inline bool prefer_blt_copy(struct sna *sna,
untiled_tlb_miss(dst_bo))
return true;
if (force_blt_ring(sna, dst_bo))
if (force_blt_ring(sna, dst_bo, src_bo))
return true;
if (kgem_bo_is_render(dst_bo) ||
......
......@@ -2969,7 +2969,7 @@ prefer_blt_copy(struct sna *sna,
if (flags & COPY_DRI && !sna->kgem.has_semaphores)
return false;
if (force_blt_ring(sna, dst_bo))
if (force_blt_ring(sna, dst_bo, src_bo))
return true;
if ((flags & COPY_SMALL ||
......
......@@ -2084,11 +2084,6 @@ try_blt(struct sna *sna,
{
struct kgem_bo *bo;
if (sna->kgem.mode == KGEM_BLT) {
DBG(("%s: already performing BLT\n", __FUNCTION__));
goto execute;
}
if (too_large(width, height)) {
DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
__FUNCTION__, width, height));
......@@ -2129,7 +2124,7 @@ try_blt(struct sna *sna,
goto execute;
}
if (sna->kgem.ring == KGEM_BLT) {
if (sna->kgem.mode == KGEM_BLT) {
DBG(("%s: already performing BLT\n", __FUNCTION__));
goto execute;
}
......@@ -2796,40 +2791,53 @@ prefer_blt_copy(struct sna *sna,
struct kgem_bo *dst_bo,
unsigned flags)
{
if (sna->kgem.mode == KGEM_BLT)
return true;
assert((flags & COPY_SYNC) == 0);
if (untiled_tlb_miss(src_bo) ||
untiled_tlb_miss(dst_bo))
untiled_tlb_miss(dst_bo)) {
DBG(("%s: TLB miss -> blt\n", __func__));
return true;
}
if (flags & COPY_DRI && !sna->kgem.has_semaphores)
if (flags & COPY_DRI && !sna->kgem.has_semaphores) {
DBG(("%s: DRI -> render\n", __func__));
return false;
}
if (force_blt_ring(sna, dst_bo))
if (force_blt_ring(sna, dst_bo, src_bo)) {
DBG(("%s: force BLT -> blt\n", __func__));
return true;
}
if ((flags & COPY_SMALL ||
(sna->render_state.gt < 3 && src_bo == dst_bo)) &&
can_switch_to_blt(sna, dst_bo, flags))
can_switch_to_blt(sna, dst_bo, flags)) {
DBG(("%s: small/self copy -> blt\n", __func__));
return true;
}
if (kgem_bo_is_render(dst_bo) ||
kgem_bo_is_render(src_bo))
kgem_bo_is_render(src_bo)) {
DBG(("%s: render bo -> render\n", __func__));
return false;
}
if (flags & COPY_LAST &&
sna->render_state.gt < 3 &&
can_switch_to_blt(sna, dst_bo, flags))
can_switch_to_blt(sna, dst_bo, flags)) {
DBG(("%s: copy last -> blt\n", __func__));
return true;
}
if (prefer_render_ring(sna, dst_bo))
if (prefer_render_ring(sna, dst_bo)) {
DBG(("%s: prefer render -> render\n", __func__));
return false;
}
if (!prefer_blt_ring(sna, dst_bo, flags))
if (!prefer_blt_ring(sna, dst_bo, flags)) {
DBG(("%s: !prefer blt -> render\n", __func__));
return false;
}
return prefer_blt_bo(sna, src_bo, dst_bo);
}
......@@ -3116,6 +3124,7 @@ gen8_render_copy(struct sna *sna, uint8_t alu,
unaligned(src_bo, src->drawable.bitsPerPixel) ||
unaligned(dst_bo, dst->drawable.bitsPerPixel)) {
fallback:
DBG(("%s: blt fallback\n", __func__));
if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
return false;
......
......@@ -2162,11 +2162,6 @@ try_blt(struct sna *sna,
{
struct kgem_bo *bo;
if (sna->kgem.mode == KGEM_BLT) {
DBG(("%s: already performing BLT\n", __FUNCTION__));
goto execute;
}
if (too_large(width, height)) {
DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
__FUNCTION__, width, height));
......@@ -2207,7 +2202,7 @@ try_blt(struct sna *sna,
goto execute;
}
if (sna->kgem.ring == KGEM_BLT) {
if (sna->kgem.mode == KGEM_BLT) {
DBG(("%s: already performing BLT\n", __FUNCTION__));
goto execute;
}
......@@ -2875,9 +2870,6 @@ prefer_blt_copy(struct sna *sna,
struct kgem_bo *dst_bo,
unsigned flags)
{
if (sna->kgem.mode == KGEM_BLT)
return true;
assert((flags & COPY_SYNC) == 0);
if (untiled_tlb_miss(src_bo) ||
......@@ -2887,7 +2879,7 @@ prefer_blt_copy(struct sna *sna,
if (flags & COPY_DRI && !sna->kgem.has_semaphores)
return false;
if (force_blt_ring(sna, dst_bo))
if (force_blt_ring(sna, dst_bo, src_bo))
return true;
if ((flags & COPY_SMALL ||
......
......@@ -686,9 +686,12 @@ static inline bool __kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo)
static inline bool kgem_bo_is_render(struct kgem_bo *bo)
{
DBG(("%s: handle=%d, rq? %d [%d]\n", __FUNCTION__,
bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq)));
DBG(("%s: handle=%d, tiling=%d, rq? %d [%d]\n", __FUNCTION__,
bo->handle, bo->tiling, bo->rq != NULL, (int)RQ_RING(bo->rq)));
assert(bo->refcnt);
if (bo->tiling >= I915_TILING_Y)
return true;
return bo->rq && RQ_RING(bo->rq) != KGEM_BLT;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment