summaryrefslogtreecommitdiff
path: root/src/intel_video.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-07-09 10:41:19 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-07-09 10:50:52 +0100
commit272d1c14a39c32ade39b5a8b080a891f2b3d6e8e (patch)
tree98485270e6a42648aa2d0a27c22e137ea1fc27fb /src/intel_video.c
parent75850e824bd66b961b9ce21696d9090169f7b28f (diff)
video: apply the crtc box checks from dri.
The dri code is much more careful in ensuring that the scan lines that is waits for are valid. Copy this code to video, with a bit of work this can be refactored, and perhaps even teach dri how to handle rotated front buffers. References: Bug 28964 - [i965gm] GPU infinite MI_WAIT_FOR_EVENT while watching video in Totem https://bugs.freedesktop.org/show_bug.cgi?id=28964 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/intel_video.c')
-rw-r--r--src/intel_video.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/src/intel_video.c b/src/intel_video.c
index 3ecc8080..cf225629 100644
--- a/src/intel_video.c
+++ b/src/intel_video.c
@@ -1273,40 +1273,66 @@ intel_wait_for_scanline(ScrnInfoPtr scrn, PixmapPtr pixmap,
xf86CrtcPtr crtc, RegionPtr clipBoxes)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
- BoxPtr box;
- pixman_box16_t box_in_crtc_coordinates;
- int pipe = -1, event, load_scan_lines_pipe;
+ pixman_box16_t box, crtc_box;
+ int pipe, event;
+ Bool full_height;
+ int y1, y2;
+ pipe = -1;
if (pixmap_is_scanout(pixmap))
pipe = intel_crtc_to_pipe(crtc);
+ if (pipe < 0)
+ return;
- if (pipe >= 0) {
- if (pipe == 0) {
- event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
- load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
- } else {
- event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
- load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
- }
+ box = *REGION_EXTENTS(unused, clipBoxes);
+
+ if (crtc->transform_in_use)
+ pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, &box);
- box = REGION_EXTENTS(unused, clipBoxes);
- box_in_crtc_coordinates = *box;
- if (crtc->transform_in_use)
- pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc,
- &box_in_crtc_coordinates);
-
- BEGIN_BATCH(5);
- /* The documentation says that the LOAD_SCAN_LINES command
- * always comes in pairs. Don't ask me why. */
- OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
- OUT_BATCH((box_in_crtc_coordinates.
- y1 << 16) | box_in_crtc_coordinates.y2);
- OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
- OUT_BATCH((box_in_crtc_coordinates.
- y1 << 16) | box_in_crtc_coordinates.y2);
- OUT_BATCH(MI_WAIT_FOR_EVENT | event);
- ADVANCE_BATCH();
+ intel_crtc_box(crtc, &crtc_box);
+ intel_box_intersect(&box, &crtc_box, &box);
+
+ /*
+ * Make sure we don't wait for a scanline that will
+ * never occur
+ */
+ y1 = (crtc_box.y1 <= box.y1) ? box.y1 - crtc_box.y1 : 0;
+ y2 = (box.y2 <= crtc_box.y2) ?
+ box.y2 - crtc_box.y1 : crtc_box.y2 - crtc_box.y1;
+
+ full_height = FALSE;
+ if (y1 == 0 && y2 == (crtc_box.y2 - crtc_box.y1))
+ full_height = TRUE;
+
+ /*
+ * Pre-965 doesn't have SVBLANK, so we need a bit
+ * of extra time for the blitter to start up and
+ * do its job for a full height blit
+ */
+ if (full_height && !IS_I965G(intel))
+ y2 -= 2;
+
+ if (pipe == 0) {
+ pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
+ event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
+ if (full_height && IS_I965G(intel))
+ event = MI_WAIT_FOR_PIPEA_SVBLANK;
+ } else {
+ pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
+ event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
+ if (full_height && IS_I965G(intel))
+ event = MI_WAIT_FOR_PIPEB_SVBLANK;
}
+
+ BEGIN_BATCH(5);
+ /* The documentation says that the LOAD_SCAN_LINES command
+ * always comes in pairs. Don't ask me why. */
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe);
+ OUT_BATCH((box.y1 << 16) | box.y2);
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe);
+ OUT_BATCH((box.y1 << 16) | box.y2);
+ OUT_BATCH(MI_WAIT_FOR_EVENT | event);
+ ADVANCE_BATCH();
}
static Bool