diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-04-02 10:58:52 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-04-02 10:58:52 +0100 |
commit | 3d7e16addb2fb5f35936aafe8e16685a91d30f59 (patch) | |
tree | b7c2a323e2724a97fa3f625e322115c79532eef8 | |
parent | f09aa788d79d36688bcfdd3b49b92367590c5f16 (diff) |
sna/gen4: Break the Video rendering loop into 16 rectangle chunks
If we feed more than 16 rectangles into the video rendering pipeline,
the GPU goes crazy and starts emitting corruption. Lalalala.
Bugzilla: https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1162046
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/gen4_render.c | 62 | ||||
-rw-r--r-- | src/sna/sna_video_textured.c | 5 |
2 files changed, 43 insertions, 24 deletions
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 1bf5ad29..c05b37b6 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -1387,37 +1387,51 @@ gen4_render_video(struct sna *sna, box = REGION_RECTS(dstRegion); nbox = REGION_NUM_RECTS(dstRegion); - while (nbox--) { - BoxRec r; + do { + int n; - r.x1 = box->x1 + pix_xoff; - r.x2 = box->x2 + pix_xoff; - r.y1 = box->y1 + pix_yoff; - r.y2 = box->y2 + pix_yoff; + n = gen4_get_rectangles(sna, &tmp, min(nbox, 16), + gen4_video_bind_surfaces); + ErrorF("n=%d/%d\n", n, nbox); + assert(n); + nbox -= n; - gen4_get_rectangles(sna, &tmp, 1, gen4_video_bind_surfaces); + do { + BoxRec r; - OUT_VERTEX(r.x2, r.y2); - OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); - OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); + r.x1 = box->x1 + pix_xoff; + r.x2 = box->x2 + pix_xoff; + r.y1 = box->y1 + pix_yoff; + r.y2 = box->y2 + pix_yoff; - OUT_VERTEX(r.x1, r.y2); - OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); - OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); + OUT_VERTEX(r.x2, r.y2); + OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); + OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); - OUT_VERTEX(r.x1, r.y1); - OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); - OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); + OUT_VERTEX(r.x1, r.y2); + OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); + OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); - if (!DAMAGE_IS_ALL(priv->gpu_damage)) { - sna_damage_add_box(&priv->gpu_damage, &r); - sna_damage_subtract_box(&priv->cpu_damage, &r); - } - box++; - } - priv->clear = false; + OUT_VERTEX(r.x1, r.y1); + OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); + OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); - gen4_vertex_flush(sna); + if (!DAMAGE_IS_ALL(priv->gpu_damage)) { + sna_damage_add_box(&priv->gpu_damage, &r); + sna_damage_subtract_box(&priv->cpu_damage, &r); + } + box++; + } while (--n); + + gen4_vertex_flush(sna); + if (!nbox) + break; + + /* VUE corruption strikes again */ + OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); + } while (1); + + priv->clear = false; return true; } diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c index bd203259..d94dbd8f 100644 --- a/src/sna/sna_video_textured.c +++ b/src/sna/sna_video_textured.c @@ -230,6 +230,11 @@ sna_video_textured_put_image(ScrnInfoPtr scrn, drw_x, drw_y, drw_w, drw_h, id, width, height, sync)); + DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__, + RegionNumRects(clip), + clip->extents.x1, clip->extents.y1, + clip->extents.x2, clip->extents.y2)); + if (buf == 0) { DBG(("%s: garbage video buffer\n", __FUNCTION__)); return BadAlloc; |