summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-03-19 08:26:01 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-03-19 08:26:01 +0000
commit1aca872ee51e10908dcc4979596ae69732e9a02a (patch)
tree9a959719fa268f0c2e7ad60d5253d7592e28acad
parentf132452da14fd09a2a3926cc9c034cb2e8c2f1a9 (diff)
sna: Haswell reintroduces MI_LOAD_SCAN_LINES
Better late than never? Interestingly only available from the BLT ring, which makes accurate waiting for XVideo (which must use the render ring) impossible in the current form - we need to render to a temporary then do a vsynced blit in this case. References: https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1156679 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_display.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index abb340a7..9068df99 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2806,12 +2806,46 @@ sna_covering_crtc(ScrnInfoPtr scrn,
return best_crtc;
}
+static bool sna_emit_wait_for_scanline_hsw(struct sna *sna,
+ xf86CrtcPtr crtc,
+ int pipe, int y1, int y2,
+ bool full_height)
+{
+ uint32_t event;
+ uint32_t *b;
+
+ if (sna->kgem.mode != KGEM_BLT)
+ return false;
+
+ b = kgem_get_batch(&sna->kgem);
+ sna->kgem.nbatch += 5;
+
+ /* The documentation says that the LOAD_SCAN_LINES command
+ * always comes in pairs. Don't ask me why. */
+ switch (pipe) {
+ case 0: event = 0; break;
+ case 1: event = 1 << 19; break;
+ case 2: event = 4 << 19; break;
+ }
+ b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | event;
+ b[3] = b[1] = (y1 << 16) | (y2-1);
+
+ switch (pipe) {
+ case 0: event = 0; break;
+ case 1: event = 1 << 8; break;
+ case 2: event = 1 << 14; break;
+ }
+ b[4] = MI_WAIT_FOR_EVENT | event;
+
+ return true;
+}
+
#define MI_LOAD_REGISTER_IMM (0x22<<23)
-static bool sna_emit_wait_for_scanline_gen7(struct sna *sna,
- xf86CrtcPtr crtc,
- int pipe, int y1, int y2,
- bool full_height)
+static bool sna_emit_wait_for_scanline_ivb(struct sna *sna,
+ xf86CrtcPtr crtc,
+ int pipe, int y1, int y2,
+ bool full_height)
{
uint32_t *b;
uint32_t event;
@@ -3022,10 +3056,12 @@ sna_wait_for_scanline(struct sna *sna,
if (sna->kgem.gen >= 0100)
ret = false;
+ else if (sna->kgem.gen >= 075)
+ ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen == 071)
ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen >= 070)
- ret = sna_emit_wait_for_scanline_gen7(sna, crtc, pipe, y1, y2, full_height);
+ ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen >= 060)
ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen >= 040)