Here's my patch below. Sorry for late response. I wonder what pixmap_is_scanout does. It always returns FALSE. Patch for intel driver 2.14.0 (the one in Ubuntu distro).
Gen6 wait for scanline event support
-------------------------------- src/i830_reg.h -------------------------------- index 93d03cf..0a5946c 100644 @@ -65,6 +65,19 @@ #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEA (0) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEB (0x1<<20)
+/* Gen6 wait for scan line support */ +#define MI_LOAD_REGISTER_IMM (0x22<<23) +#define MI_DISPLAY_PIPEA_SCAN_LINE_WAIT (1) +#define MI_DISPLAY_PIPEB_SCAN_LINE_WAIT (1<<8) +#define MI_DISPLAY_PIPEA_VBLANK_WAIT (1<<3) +#define MI_DISPLAY_PIPEB_VBLANK_WAIT (1<<11) + +/* Scan lines register */ +#define DE_LOAD_SL_ADDR (0x4f100) +#define DE_LOAD_SL_PIPEA (0x110<<29) +#define DE_LOAD_SL_PIPEB (0x111<<29) +#define DERRMR_ADDR (0x44050) + /* BLT commands */ #define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3)) #define COLOR_BLT_WRITE_ALPHA (1<<21)
------------------------------ src/intel_video.c ------------------------------ index 5294f73..506178f 100644 @@ -1365,6 +1365,83 @@ intel_wait_for_scanline(ScrnInfoPtr scrn, PixmapPtr pixmap, ADVANCE_BATCH(); }
+static void +intel_wait_for_scanline_gen6(ScrnInfoPtr scrn, PixmapPtr pixmap, + xf86CrtcPtr crtc, RegionPtr clipBoxes) +{ + intel_screen_private *intel = intel_get_screen_private(scrn); + 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; + + box = *REGION_EXTENTS(unused, clipBoxes); + + if (crtc->transform_in_use) + pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, &box); + + /* We could presume the clip was correctly computed... */ + 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; + + if (y2 <= y1) + return; + + full_height = FALSE; + if (y1 == 0 && y2 == (crtc_box.y2 - crtc_box.y1)) + full_height = TRUE; + + if (pipe == 0) { + pipe = DE_LOAD_SL_PIPEA; + event = MI_DISPLAY_PIPEA_SCAN_LINE_WAIT; + if (full_height) + event = MI_DISPLAY_PIPEA_VBLANK_WAIT; + } else { + pipe = DE_LOAD_SL_PIPEB; + event = MI_DISPLAY_PIPEB_SCAN_LINE_WAIT; + if (full_height) + event = MI_DISPLAY_PIPEB_VBLANK_WAIT; + } + + /* According to docs only upper 10 bits are significant */ + if(!(y2 & 0x3)) + y2 += 8; + + + y1 &= 0x1ff8; + y2 &= 0x1ff8; + + if (crtc->mode.Flags & V_INTERLACE) { + /* DSL count field lines */ + y1 /= 2; + y2 /= 2; + } + + BEGIN_BATCH(4); + OUT_BATCH(MI_LOAD_REGISTER_IMM | 1); + OUT_BATCH(DE_LOAD_SL_ADDR); + OUT_BATCH(pipe | (y1 << 16) | y2); + OUT_BATCH(MI_WAIT_FOR_EVENT | event); + ADVANCE_BATCH(); +} + + static Bool intel_setup_video_buffer(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int alloc_size, int id, unsigned char *buf) @@ -1578,8 +1655,11 @@ I830PutImageTextured(ScrnInfoPtr scrn, return BadAlloc; }
- if (crtc && adaptor_priv->SyncToVblank != 0 && INTEL_INFO(intel)->gen < 60) { - intel_wait_for_scanline(scrn, pixmap, crtc, clipBoxes); + if (crtc && adaptor_priv->SyncToVblank != 0) { + if(INTEL_INFO(intel)->gen < 60) + intel_wait_for_scanline(scrn, pixmap, crtc, clipBoxes); + else + intel_wait_for_scanline_gen6(scrn, pixmap, crtc, clipBoxes); }
if (INTEL_INFO(intel)->gen >= 60) {
Here's my patch below. Sorry for late response. I wonder what pixmap_is_scanout does. It always returns FALSE. Patch for intel driver 2.14.0 (the one in Ubuntu distro).
Gen6 wait for scanline event support
------- ------- ------- ------- ---- src/i830_reg.h ------- ------- ------- ------- ---- SCAN_LINES_ DISPLAY_ PIPEA (0) SCAN_LINES_ DISPLAY_ PIPEB (0x1<<20)
index 93d03cf..0a5946c 100644
@@ -65,6 +65,19 @@
#define MI_LOAD_
#define MI_LOAD_
+/* Gen6 wait for scan line support */ REGISTER_ IMM (0x22<<23) PIPEA_SCAN_ LINE_WAIT (1) PIPEB_SCAN_ LINE_WAIT (1<<8) PIPEA_VBLANK_ WAIT (1<<3) PIPEB_VBLANK_ WAIT (1<<11) |(0x40< <22)|(0x3) ) WRITE_ALPHA (1<<21)
+#define MI_LOAD_
+#define MI_DISPLAY_
+#define MI_DISPLAY_
+#define MI_DISPLAY_
+#define MI_DISPLAY_
+
+/* Scan lines register */
+#define DE_LOAD_SL_ADDR (0x4f100)
+#define DE_LOAD_SL_PIPEA (0x110<<29)
+#define DE_LOAD_SL_PIPEB (0x111<<29)
+#define DERRMR_ADDR (0x44050)
+
/* BLT commands */
#define COLOR_BLT_CMD ((2<<29)
#define COLOR_BLT_
------- ------- ------- ------- -- src/intel_video.c ------- ------- ------- ------- -- for_scanline( ScrnInfoPtr scrn, PixmapPtr pixmap,
index 5294f73..506178f 100644
@@ -1365,6 +1365,83 @@ intel_wait_
ADVANCE_BATCH();
}
+static void wait_for_ scanline_ gen6(ScrnInfoPt r scrn, PixmapPtr pixmap, private *intel = intel_get_ screen_ private( scrn); is_scanout( pixmap) ) to_pipe( crtc); EXTENTS( unused, clipBoxes); transform_ in_use) f_transform_ bounds( &crtc-> f_framebuffer_ to_crtc, &box); box(crtc, &crtc_box); intersect( &box, &crtc_box, &box); PIPEA_SCAN_ LINE_WAIT; PIPEA_VBLANK_ WAIT; PIPEB_SCAN_ LINE_WAIT; PIPEB_VBLANK_ WAIT; MI_LOAD_ REGISTER_ IMM | 1); DE_LOAD_ SL_ADDR) ; MI_WAIT_ FOR_EVENT | event); setup_video_ buffer( ScrnInfoPtr scrn, intel_adaptor_ private *adaptor_priv, tured(ScrnInfoP tr scrn,
+intel_
+ xf86CrtcPtr crtc, RegionPtr clipBoxes)
+{
+ intel_screen_
+ pixman_box16_t box, crtc_box;
+ int pipe, event;
+ Bool full_height;
+ int y1, y2;
+
+ pipe = -1;
+ if (pixmap_
+ {
+ pipe = intel_crtc_
+ }
+ if (pipe < 0)
+ return;
+
+ box = *REGION_
+
+ if (crtc->
+ pixman_
+
+ /* We could presume the clip was correctly computed... */
+ intel_crtc_
+ intel_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;
+
+ if (y2 <= y1)
+ return;
+
+ full_height = FALSE;
+ if (y1 == 0 && y2 == (crtc_box.y2 - crtc_box.y1))
+ full_height = TRUE;
+
+ if (pipe == 0) {
+ pipe = DE_LOAD_SL_PIPEA;
+ event = MI_DISPLAY_
+ if (full_height)
+ event = MI_DISPLAY_
+ } else {
+ pipe = DE_LOAD_SL_PIPEB;
+ event = MI_DISPLAY_
+ if (full_height)
+ event = MI_DISPLAY_
+ }
+
+ /* According to docs only upper 10 bits are significant */
+ if(!(y2 & 0x3))
+ y2 += 8;
+
+
+ y1 &= 0x1ff8;
+ y2 &= 0x1ff8;
+
+ if (crtc->mode.Flags & V_INTERLACE) {
+ /* DSL count field lines */
+ y1 /= 2;
+ y2 /= 2;
+ }
+
+ BEGIN_BATCH(4);
+ OUT_BATCH(
+ OUT_BATCH(
+ OUT_BATCH(pipe | (y1 << 16) | y2);
+ OUT_BATCH(
+ ADVANCE_BATCH();
+}
+
+
static Bool
intel_
int alloc_size, int id, unsigned char *buf)
@@ -1578,8 +1655,11 @@ I830PutImageTex
return BadAlloc;
}
- if (crtc && adaptor_ priv->SyncToVbl ank != 0 && INTEL_INFO( intel)- >gen < 60) { for_scanline( scrn, pixmap, crtc, clipBoxes); priv->SyncToVbl ank != 0) { INFO(intel) ->gen < 60) for_scanline( scrn, pixmap, crtc, clipBoxes); for_scanline_ gen6(scrn, pixmap, crtc, clipBoxes);
- intel_wait_
+ if (crtc && adaptor_
+ if(INTEL_
+ intel_wait_
+ else
+ intel_wait_
}
if (INTEL_ INFO(intel) ->gen >= 60) {