summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-04-02 10:58:52 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-04-02 10:58:52 +0100
commit3d7e16addb2fb5f35936aafe8e16685a91d30f59 (patch)
treeb7c2a323e2724a97fa3f625e322115c79532eef8
parentf09aa788d79d36688bcfdd3b49b92367590c5f16 (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.c62
-rw-r--r--src/sna/sna_video_textured.c5
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;