diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-12-08 22:39:32 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-12-08 22:42:11 +0000 |
commit | 4e4e10935d2815fb62aeaedbfffe10aad115ec0b (patch) | |
tree | 67cb878a98a00986224fed1d0d634ea3463319e2 | |
parent | cef11795f627a393d4254845b0a19eefbf6c782c (diff) | |
download | xf86-video-intel-4e4e10935d2815fb62aeaedbfffe10aad115ec0b.tar.gz xf86-video-intel-4e4e10935d2815fb62aeaedbfffe10aad115ec0b.tar.bz2 xf86-video-intel-4e4e10935d2815fb62aeaedbfffe10aad115ec0b.zip |
sna: Flush upon change of target if GPU is idle
The aim is to improve GPU concurrency by keeping it busy. The possible
complication is that we incur more overhead due to small batches.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/gen2_render.c | 14 | ||||
-rw-r--r-- | src/sna/gen3_render.c | 14 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 10 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 12 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 30 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 22 | ||||
-rw-r--r-- | src/sna/kgem.c | 2 | ||||
-rw-r--r-- | src/sna/kgem.h | 7 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 24 | ||||
-rw-r--r-- | src/sna/sna_blt.c | 12 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 26 | ||||
-rw-r--r-- | src/sna/sna_io.c | 14 | ||||
-rw-r--r-- | src/sna/sna_video_textured.c | 5 |
13 files changed, 100 insertions, 92 deletions
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c index b37af9b96..2123cb9e1 100644 --- a/src/sna/gen2_render.c +++ b/src/sna/gen2_render.c @@ -536,9 +536,9 @@ static void gen2_emit_invariant(struct sna *sna) } static void -gen2_get_batch(struct sna *sna) +gen2_get_batch(struct sna *sna, const struct sna_composite_op *op) { - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch(&sna->kgem, INVARIANT_SIZE+40)) { DBG(("%s: flushing batch: size %d > %d\n", @@ -662,7 +662,7 @@ static void gen2_emit_composite_state(struct sna *sna, uint32_t cblend, ablend; int tex; - gen2_get_batch(sna); + gen2_get_batch(sna, op); if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { if (op->src.bo == op->dst.bo || op->mask.bo == op->dst.bo) @@ -2146,7 +2146,7 @@ static void gen2_emit_composite_spans_state(struct sna *sna, { uint32_t unwind; - gen2_get_batch(sna); + gen2_get_batch(sna, &op->base); gen2_emit_target(sna, &op->base); unwind = sna->kgem.nbatch; @@ -2404,7 +2404,7 @@ static void gen2_emit_fill_composite_state(struct sna *sna, { uint32_t ls1; - gen2_get_batch(sna); + gen2_get_batch(sna, op); gen2_emit_target(sna, op); ls1 = sna->kgem.nbatch; @@ -2589,7 +2589,7 @@ static void gen2_emit_fill_state(struct sna *sna, { uint32_t ls1; - gen2_get_batch(sna); + gen2_get_batch(sna, op); gen2_emit_target(sna, op); ls1 = sna->kgem.nbatch; @@ -2882,7 +2882,7 @@ static void gen2_emit_copy_state(struct sna *sna, const struct sna_composite_op { uint32_t ls1, v; - gen2_get_batch(sna); + gen2_get_batch(sna, op); if (kgem_bo_is_dirty(op->src.bo)) { if (op->src.bo == op->dst.bo) diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c index 9dcdfcdb5..b092976fe 100644 --- a/src/sna/gen3_render.c +++ b/src/sna/gen3_render.c @@ -1298,9 +1298,9 @@ static void gen3_emit_invariant(struct sna *sna) #define MAX_OBJECTS 3 /* worst case: dst + src + mask */ static void -gen3_get_batch(struct sna *sna) +gen3_get_batch(struct sna *sna, const struct sna_composite_op *op) { - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch(&sna->kgem, 200)) { DBG(("%s: flushing batch: size %d > %d\n", @@ -1389,7 +1389,7 @@ static void gen3_emit_composite_state(struct sna *sna, unsigned int tex_count, n; uint32_t ss2; - gen3_get_batch(sna); + gen3_get_batch(sna, op); if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { if (op->src.bo == op->dst.bo || op->mask.bo == op->dst.bo) @@ -3841,9 +3841,9 @@ gen3_emit_video_state(struct sna *sna, } static void -gen3_video_get_batch(struct sna *sna) +gen3_video_get_batch(struct sna *sna, struct kgem_bo *bo) { - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_batch(&sna->kgem, 120) || !kgem_check_reloc(&sna->kgem, 4) || @@ -3934,13 +3934,13 @@ gen3_render_video(struct sna *sna, __FUNCTION__, dxo, dyo, src_scale_x, src_scale_y, pix_xoff, pix_yoff)); - gen3_video_get_batch(sna); + gen3_video_get_batch(sna, dst_bo); gen3_emit_video_state(sna, video, frame, pixmap, dst_bo, width, height); do { int nbox_this_time = gen3_get_inline_rectangles(sna, nbox, 4); if (nbox_this_time == 0) { - gen3_video_get_batch(sna); + gen3_video_get_batch(sna, dst_bo); gen3_emit_video_state(sna, video, frame, pixmap, dst_bo, width, height); nbox_this_time = gen3_get_inline_rectangles(sna, nbox, 4); diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 18a6bf63e..14ac123c8 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -1222,9 +1222,9 @@ gen4_emit_invariant(struct sna *sna) } static void -gen4_get_batch(struct sna *sna) +gen4_get_batch(struct sna *sna, const struct sna_composite_op *op) { - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", @@ -1446,7 +1446,7 @@ gen4_bind_surfaces(struct sna *sna, uint32_t *binding_table; uint16_t offset; - gen4_get_batch(sna); + gen4_get_batch(sna, op); binding_table = gen4_composite_get_binding_table(sna, &offset); @@ -1637,7 +1637,7 @@ static void gen4_video_bind_surfaces(struct sna *sna, n_src = 1; } - gen4_get_batch(sna); + gen4_get_batch(sna, op); binding_table = gen4_composite_get_binding_table(sna, &offset); @@ -2798,7 +2798,7 @@ gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) uint32_t *binding_table; uint16_t offset; - gen4_get_batch(sna); + gen4_get_batch(sna, op); binding_table = gen4_composite_get_binding_table(sna, &offset); diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 284e8da15..d0e570e0d 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -1227,9 +1227,9 @@ gen5_emit_invariant(struct sna *sna) } static void -gen5_get_batch(struct sna *sna) +gen5_get_batch(struct sna *sna, const struct sna_composite_op *op) { - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", @@ -1447,7 +1447,7 @@ static void gen5_bind_surfaces(struct sna *sna, uint32_t *binding_table; uint16_t offset; - gen5_get_batch(sna); + gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); @@ -1636,7 +1636,7 @@ static void gen5_video_bind_surfaces(struct sna *sna, n_src = 1; } - gen5_get_batch(sna); + gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); binding_table[0] = @@ -2808,7 +2808,7 @@ gen5_copy_bind_surfaces(struct sna *sna, uint32_t *binding_table; uint16_t offset; - gen5_get_batch(sna); + gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); @@ -3137,7 +3137,7 @@ gen5_fill_bind_surfaces(struct sna *sna, uint32_t *binding_table; uint16_t offset; - gen5_get_batch(sna); + gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 50df5572e..1677a473b 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -1694,10 +1694,10 @@ gen6_choose_composite_vertex_buffer(const struct sna_composite_op *op) return id; } -static void -gen6_get_batch(struct sna *sna) +static bool +gen6_get_batch(struct sna *sna, const struct sna_composite_op *op) { - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", @@ -1709,6 +1709,8 @@ gen6_get_batch(struct sna *sna) if (sna->render_state.gen6.needs_invariant) gen6_emit_invariant(sna); + + return kgem_bo_is_dirty(op->dst.bo); } static void gen6_emit_composite_state(struct sna *sna, @@ -1718,8 +1720,7 @@ static void gen6_emit_composite_state(struct sna *sna, uint16_t offset; bool dirty; - gen6_get_batch(sna); - dirty = kgem_bo_is_dirty(op->dst.bo); + dirty = gen6_get_batch(sna, op); binding_table = gen6_composite_get_binding_table(sna, &offset); @@ -1918,8 +1919,7 @@ static void gen6_emit_video_state(struct sna *sna, bool dirty; int n_src, n; - gen6_get_batch(sna); - dirty = kgem_bo_is_dirty(op->dst.bo); + dirty = gen6_get_batch(sna, op); src_surf_base[0] = 0; src_surf_base[1] = 0; @@ -2022,7 +2022,7 @@ gen6_render_video(struct sna *sna, 2); tmp.priv = frame; - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { kgem_submit(&sna->kgem); assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)); @@ -2847,7 +2847,7 @@ gen6_render_composite(struct sna *sna, tmp->boxes = gen6_render_composite_boxes; tmp->done = gen6_render_composite_done; - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { @@ -3219,7 +3219,7 @@ gen6_render_composite_spans(struct sna *sna, tmp->boxes = gen6_render_composite_spans_boxes; tmp->done = gen6_render_composite_spans_done; - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->base.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { @@ -3253,8 +3253,7 @@ gen6_emit_copy_state(struct sna *sna, uint16_t offset; bool dirty; - gen6_get_batch(sna); - dirty = kgem_bo_is_dirty(op->dst.bo); + dirty = gen6_get_batch(sna, op); binding_table = gen6_composite_get_binding_table(sna, &offset); @@ -3482,7 +3481,7 @@ fallback_blt: assert(GEN6_SAMPLER(tmp.u.gen6.flags) == COPY_SAMPLER); assert(GEN6_VERTEX(tmp.u.gen6.flags) == COPY_VERTEX); - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { @@ -3638,7 +3637,7 @@ fallback: assert(GEN6_SAMPLER(op->base.u.gen6.flags) == COPY_SAMPLER); assert(GEN6_VERTEX(op->base.u.gen6.flags) == COPY_VERTEX); - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) @@ -3661,8 +3660,7 @@ gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op) uint16_t offset; bool dirty; - gen6_get_batch(sna); - dirty = kgem_bo_is_dirty(op->dst.bo); + dirty = gen6_get_batch(sna, op); binding_table = gen6_composite_get_binding_table(sna, &offset); diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index eb34ff2f9..fea5a1013 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -1810,9 +1810,9 @@ gen7_choose_composite_vertex_buffer(const struct sna_composite_op *op) } static void -gen7_get_batch(struct sna *sna) +gen7_get_batch(struct sna *sna, const struct sna_composite_op *op) { - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", @@ -1835,7 +1835,7 @@ static void gen7_emit_composite_state(struct sna *sna, uint32_t *binding_table; uint16_t offset; - gen7_get_batch(sna); + gen7_get_batch(sna, op); binding_table = gen7_composite_get_binding_table(sna, &offset); @@ -2031,7 +2031,7 @@ static void gen7_emit_video_state(struct sna *sna, uint16_t offset; int n_src, n; - gen7_get_batch(sna); + gen7_get_batch(sna, op); src_surf_base[0] = 0; src_surf_base[1] = 0; @@ -2134,7 +2134,7 @@ gen7_render_video(struct sna *sna, 2); tmp.priv = frame; - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { kgem_submit(&sna->kgem); assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)); @@ -2955,7 +2955,7 @@ gen7_render_composite(struct sna *sna, tmp->boxes = gen7_render_composite_boxes; tmp->done = gen7_render_composite_done; - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { @@ -3309,7 +3309,7 @@ gen7_render_composite_spans(struct sna *sna, tmp->boxes = gen7_render_composite_spans_boxes; tmp->done = gen7_render_composite_spans_done; - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->base.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { @@ -3342,7 +3342,7 @@ gen7_emit_copy_state(struct sna *sna, uint32_t *binding_table; uint16_t offset; - gen7_get_batch(sna); + gen7_get_batch(sna, op); binding_table = gen7_composite_get_binding_table(sna, &offset); @@ -3563,7 +3563,7 @@ fallback_blt: tmp.u.gen7.flags = COPY_FLAGS(alu); - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) @@ -3711,7 +3711,7 @@ fallback: op->base.u.gen7.flags = COPY_FLAGS(alu); - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) @@ -3739,7 +3739,7 @@ gen7_emit_fill_state(struct sna *sna, const struct sna_composite_op *op) * specific kernel. */ - gen7_get_batch(sna); + gen7_get_batch(sna, op); binding_table = gen7_composite_get_binding_table(sna, &offset); diff --git a/src/sna/kgem.c b/src/sna/kgem.c index c497ce7bf..47dd7d5db 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -5228,7 +5228,7 @@ kgem_replace_bo(struct kgem *kgem, dst->unique_id = kgem_get_unique_id(kgem); dst->refcnt = 1; - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, dst); if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc(kgem, 2) || !kgem_check_many_bo_fenced(kgem, src, dst, NULL)) { diff --git a/src/sna/kgem.h b/src/sna/kgem.h index e7e53af57..5cd22ccfb 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -347,7 +347,9 @@ static inline void kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) void kgem_clear_dirty(struct kgem *kgem); -static inline void kgem_set_mode(struct kgem *kgem, enum kgem_mode mode) +static inline void kgem_set_mode(struct kgem *kgem, + enum kgem_mode mode, + struct kgem_bo *bo) { assert(!kgem->wedged); @@ -355,6 +357,9 @@ static inline void kgem_set_mode(struct kgem *kgem, enum kgem_mode mode) kgem_submit(kgem); #endif + if (kgem->mode && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) + kgem_submit(kgem); + if (kgem->mode == mode) return; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 51ea1a876..886bff84a 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -3800,7 +3800,7 @@ sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, x += dx + drawable->x; y += dy + drawable->y; - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); /* Region is pre-clipped and translated into pixmap space */ box = REGION_RECTS(region); @@ -3922,7 +3922,7 @@ sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, x += dx + drawable->x; y += dy + drawable->y; - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); skip = h * BitmapBytePad(w + left); for (i = 1 << (gc->depth-1); i; i >>= 1, bits += skip) { @@ -6137,7 +6137,7 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc, br13 |= blt_depth(drawable->depth) << 24; br13 |= copy_ROP[gc->alu] << 16; - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, arg->bo); do { int bx1 = (box->x1 + sx) & ~7; int bx2 = (box->x2 + sx + 7) & ~7; @@ -6301,7 +6301,7 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc, br13 |= blt_depth(drawable->depth) << 24; br13 |= copy_ROP[gc->alu] << 16; - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, arg->bo); do { int bx1 = (box->x1 + sx) & ~7; int bx2 = (box->x2 + sx + 7) & ~7; @@ -9892,7 +9892,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable, DBG(("%s x %d [(%d, %d)x(%d, %d)...], clipped=%x\n", __FUNCTION__, n, r->x, r->y, r->width, r->height, clipped)); - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); if (!kgem_check_batch(&sna->kgem, 8+2*3) || !kgem_check_reloc(&sna->kgem, 2) || !kgem_check_bo_fenced(&sna->kgem, bo)) { @@ -10526,7 +10526,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable, } while (--j); } - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); if (!kgem_check_batch(&sna->kgem, 9 + 2*3) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { @@ -10802,7 +10802,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable, origin->x, origin->y)); get_drawable_deltas(drawable, pixmap, &dx, &dy); - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); br00 = 3 << 20; br13 = bo->pitch; @@ -11498,7 +11498,7 @@ sna_poly_fill_rect_stippled_n_blt__imm(DrawablePtr drawable, clipped, gc->alu, gc->fillStyle == FillOpaqueStippled)); get_drawable_deltas(drawable, pixmap, &dx, &dy); - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); br00 = XY_MONO_SRC_COPY_IMM | 3 << 20; br13 = bo->pitch; @@ -11643,7 +11643,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable, extents, clipped); get_drawable_deltas(drawable, pixmap, &dx, &dy); - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); br00 = XY_MONO_SRC_COPY | 3 << 20; br13 = bo->pitch; @@ -12284,7 +12284,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc, bo, drawable->bitsPerPixel, bg, extents, REGION_NUM_RECTS(clip)); - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); if (!kgem_check_batch(&sna->kgem, 16) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { @@ -12929,7 +12929,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc, bo, drawable->bitsPerPixel, bg, extents, REGION_NUM_RECTS(clip)); - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); if (!kgem_check_batch(&sna->kgem, 16) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { @@ -13309,7 +13309,7 @@ sna_push_pixels_solid_blt(GCPtr gc, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); - kgem_set_mode(&sna->kgem, KGEM_BLT); + kgem_set_mode(&sna->kgem, KGEM_BLT, bo); /* Region is pre-clipped and translated into pixmap space */ box = REGION_RECTS(region); diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c index 2248c4d1c..e9ca0dd64 100644 --- a/src/sna/sna_blt.c +++ b/src/sna/sna_blt.c @@ -145,7 +145,7 @@ static bool sna_blt_fill_init(struct sna *sna, blt->pixel = pixel; blt->bpp = bpp; - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, bo); if (!kgem_check_batch(kgem, 12) || !kgem_check_bo_fenced(kgem, bo)) { _kgem_submit(kgem); @@ -289,7 +289,7 @@ static bool sna_blt_copy_init(struct sna *sna, case 8: break; } - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, dst); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) { _kgem_submit(kgem); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) @@ -341,7 +341,7 @@ static bool sna_blt_alpha_fixup_init(struct sna *sna, } blt->pixel = alpha; - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, dst); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) { _kgem_submit(kgem); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) @@ -2263,7 +2263,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu, return false; } - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, bo); if (!kgem_check_batch(kgem, 6) || !kgem_check_reloc(kgem, 1) || !kgem_check_bo_fenced(kgem, bo)) { @@ -2339,7 +2339,7 @@ bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu, case 8: break; } - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, bo); if (!kgem_check_batch(kgem, 12) || !kgem_check_bo_fenced(kgem, bo)) { _kgem_submit(kgem); @@ -2512,7 +2512,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu, kgem->nreloc--; } - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, dst_bo); if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc(kgem, 2) || !kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) { diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 69761437e..445399704 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -492,19 +492,17 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) DamageRegionProcessPending(&pixmap->drawable); } -static void sna_dri_select_mode(struct sna *sna, struct kgem_bo *src, bool sync) +static void sna_dri_select_mode(struct sna *sna, struct kgem_bo *dst, struct kgem_bo *src, bool sync) { struct drm_i915_gem_busy busy; int mode; - if (sna->kgem.gen < 060) { - kgem_set_mode(&sna->kgem, KGEM_BLT); + if (sna->kgem.gen < 060) return; - } if (sync) { DBG(("%s: sync, force RENDER ring\n", __FUNCTION__)); - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, dst); return; } @@ -515,7 +513,7 @@ static void sna_dri_select_mode(struct sna *sna, struct kgem_bo *src, bool sync) if (sna->kgem.has_semaphores) { DBG(("%s: have sempahores, prefering RENDER\n", __FUNCTION__)); - kgem_set_mode(&sna->kgem, KGEM_RENDER); + kgem_set_mode(&sna->kgem, KGEM_RENDER, dst); return; } @@ -526,8 +524,14 @@ static void sna_dri_select_mode(struct sna *sna, struct kgem_bo *src, bool sync) DBG(("%s: src busy?=%x\n", __FUNCTION__, busy.busy)); if (busy.busy == 0) { - DBG(("%s: src is idle, using defaults\n", __FUNCTION__)); - return; + busy.handle = dst->handle; + if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy)) + return; + DBG(("%s: dst busy?=%x\n", __FUNCTION__, busy.busy)); + if (busy.busy == 0) { + DBG(("%s: src/dst is idle, using defaults\n", __FUNCTION__)); + return; + } } /* Sandybridge introduced a separate ring which it uses to @@ -611,7 +615,7 @@ sna_dri_copy_to_front(struct sna *sna, DrawablePtr draw, RegionPtr region, if (sync) sync = sna_pixmap_is_scanout(sna, pixmap); - sna_dri_select_mode(sna, src_bo, sync); + sna_dri_select_mode(sna, dst_bo, src_bo, sync); } else sync = false; @@ -755,7 +759,7 @@ sna_dri_copy_from_front(struct sna *sna, DrawablePtr draw, RegionPtr region, dst_bo, -draw->x, -draw->y, boxes, n); } else { - sna_dri_select_mode(sna, src_bo, false); + sna_dri_select_mode(sna, dst_bo, src_bo, false); sna->render.copy_boxes(sna, GXcopy, pixmap, src_bo, dx, dy, (PixmapPtr)draw, dst_bo, -draw->x, -draw->y, @@ -804,7 +808,7 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region, dst_bo, 0, 0, boxes, n); } else { - sna_dri_select_mode(sna, src_bo, false); + sna_dri_select_mode(sna, dst_bo, src_bo, false); sna->render.copy_boxes(sna, GXcopy, (PixmapPtr)draw, src_bo, 0, 0, (PixmapPtr)draw, dst_bo, 0, 0, diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index bb7f9f9dc..ec254fc57 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -378,9 +378,9 @@ fallback: case 1: break; } - kgem_set_mode(kgem, KGEM_BLT); - if (!kgem_check_reloc_and_exec(kgem, 2) || - !kgem_check_batch(kgem, 8) || + kgem_set_mode(kgem, KGEM_BLT, dst_bo); + if (!kgem_check_batch(kgem, 8) || + !kgem_check_reloc_and_exec(kgem, 2) || !kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); @@ -824,7 +824,7 @@ tile: case 8: break; } - kgem_set_mode(kgem, KGEM_BLT); + kgem_set_mode(kgem, KGEM_BLT, dst_bo); if (!kgem_check_batch(kgem, 8) || !kgem_check_reloc_and_exec(kgem, 2) || !kgem_check_bo_fenced(kgem, dst_bo)) { @@ -1193,9 +1193,9 @@ tile: case 8: break; } - kgem_set_mode(kgem, KGEM_BLT); - if (!kgem_check_reloc_and_exec(kgem, 2) || - !kgem_check_batch(kgem, 8) || + kgem_set_mode(kgem, KGEM_BLT, dst_bo); + if (!kgem_check_batch(kgem, 8) || + !kgem_check_reloc_and_exec(kgem, 2) || !kgem_check_bo_fenced(kgem, dst_bo)) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c index f420769a8..8db8b6fcd 100644 --- a/src/sna/sna_video_textured.c +++ b/src/sna/sna_video_textured.c @@ -275,11 +275,12 @@ sna_video_textured_put_image(ScrnInfoPtr scrn, } } - kgem_set_mode(&sna->kgem, KGEM_RENDER); if (crtc && video->SyncToVblank != 0 && - sna_pixmap_is_scanout(sna, pixmap)) + sna_pixmap_is_scanout(sna, pixmap)) { + kgem_set_mode(&sna->kgem, KGEM_RENDER, sna_pixmap(pixmap)->gpu_bo); flush = sna_wait_for_scanline(sna, pixmap, crtc, &clip->extents); + } ret = Success; if (!sna->render.video(sna, video, &frame, clip, |