Comment 62 for bug 755841

Revision history for this message
In , Dmitry Savin (envelsavinds) wrote :

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) {