diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-03-19 08:26:01 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-03-19 08:26:01 +0000 |
commit | 1aca872ee51e10908dcc4979596ae69732e9a02a (patch) | |
tree | 9a959719fa268f0c2e7ad60d5253d7592e28acad | |
parent | f132452da14fd09a2a3926cc9c034cb2e8c2f1a9 (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.c | 46 |
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) |