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>
This commit is contained in:
Chris Wilson 2012-12-08 22:39:32 +00:00
parent cef11795f6
commit 4e4e10935d
13 changed files with 100 additions and 92 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)) {

View File

@ -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;

View File

@ -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);

View File

@ -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)) {

View File

@ -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,

View File

@ -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);

View File

@ -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,