[Intel-gfx] [SNB] video tearing (wait for scanline support patch)

Dmitry Savin envelsavinds at gmail.com
Mon Jun 6 19:30:19 CEST 2011


Hi,
I've made the following patch for Gen6 wait for scanline support.
pixmap_is_scanout always gives FALSE. What does it really mean? When I
comment it I've got GPU lock up while waiting for scanline. According to
specs I loaded DE_LOAD_SL register but it seems to me that it doesn't work.
Finally, I've tested it with only wait for VBLANK. And as you may suggest it
didn't help. The same tearing issue happens with even 1st generation Core
video. Why am I wrong? Patch made for 2.14.0.

    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) {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20110606/2a731243/attachment.html>


More information about the Intel-gfx mailing list