diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-07-09 10:41:19 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-07-09 10:50:52 +0100 |
commit | 272d1c14a39c32ade39b5a8b080a891f2b3d6e8e (patch) | |
tree | 98485270e6a42648aa2d0a27c22e137ea1fc27fb /src/intel_video.c | |
parent | 75850e824bd66b961b9ce21696d9090169f7b28f (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.c | 82 |
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 |