NEWS                        |   39 +++++++++++++
 configure.ac                |    2 
 src/intel_driver.c          |    2 
 src/intel_glamor.c          |   37 +++++++------
 src/sna/compiler.h          |    2 
 src/sna/gen3_render.c       |  124 +++++++++++++++++++-------------------------
 src/sna/gen4_render.c       |    4 -
 src/sna/gen4_vertex.c       |   25 +-------
 src/sna/gen5_render.c       |    4 -
 src/sna/gen6_render.c       |    4 -
 src/sna/gen7_render.c       |   26 ++++++++-
 src/sna/kgem.c              |   87 +++++++++++++++++++++++++-----
 src/sna/kgem.h              |    2 
 src/sna/sna.h               |   15 +++++
 src/sna/sna_accel.c         |   68 ++++++++++++------------
 src/sna/sna_display.c       |   49 +++++++++++++++--
 src/sna/sna_dri.c           |   67 +++++++++++++++--------
 src/sna/sna_glyphs.c        |   14 +++-
 src/sna/sna_io.c            |   15 -----
 src/sna/sna_render.c        |   26 ++++++++-
 src/sna/sna_render_inline.h |   14 ++--
 src/sna/sna_tiling.c        |   15 -----
 src/sna/sna_trapezoids.c    |    4 -
 test/Makefile.am            |    1 
 test/dri2-race.c            |  113 ++++++++++++++++++++++++++++++++++++++++
 25 files changed, 526 insertions(+), 233 deletions(-)

New commits:
commit 4adebfed415cf58599b22e873f32e7ce2eaa6542
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Mar 21 08:53:12 2013 +0000

    2.21.5 release

diff --git a/NEWS b/NEWS
index cb82e52..05a20fa 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,42 @@
+Release 2.21.5 (2013-03-21)
+===========================
+Haswell reintroduces a command to load the scanline window from the
+command stream and so requires its own specialised wait-for-vsync routine
+- failure to do so was then causing hangs when trying to do tearfree video
+or use a compositor.
+
+ * Prevent buffer leak if a non-fullscreen Window is closed with multiple
+   pending swap events.
+
+ * Fix offset transformation for fallback gradient paths.
+   https://bugs.freedesktop.org/show_bug.cgi?id=62198
+
+ * Prevent Glamor from crashing if misconfigured.
+   Thanks to Michel Dänzer.
+
+ * Prevent UXA from crashing if torn down during PreInit.
+   Thanks to Aaron Plattner.
+
+ * Prevent miscompilation with different functional units having different
+   compiler flags. Some functions were expected to be inlined and so
+   recompiled with the current target. However, some compilers were
+   choosing to emit subroutine calls instead without noticing that the
+   ABI was different between the caller and callee - causing corruption.
+   https://bugs.freedesktop.org/show_bug.cgi?id=62198
+
+ * Fix rendering of CompositeTriFan with recent Xorg.
+
+ * Apply the video src-offset fix highlighted in the last release!
+   A typo prevented the fix from working for gen4+.
+   https://bugs.freedesktop.org/show_bug.cgi?id=62343
+
+ * Fix rendering of multiple glyphs to very large destination surfaces
+   
https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1156387
+
+ * Fix scanline waits for Haswell
+   
https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1156679
+
+
 Release 2.21.4 (2013-03-11)
 ===========================
 More bugs, more fixes, more releases. A minor new feature being introduced
diff --git a/configure.ac b/configure.ac
index 8fea817..de3990d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-video-intel],
-        [2.21.4],
+        [2.21.5],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-video-intel])
 AC_CONFIG_SRCDIR([Makefile.am])

commit 1aca872ee51e10908dcc4979596ae69732e9a02a
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Tue Mar 19 08:26:01 2013 +0000

    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 <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index abb340a..9068df9 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)

commit f132452da14fd09a2a3926cc9c034cb2e8c2f1a9
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Tue Mar 19 07:57:30 2013 +0000

    sna: Ignore vsync waits on tiny scanline ranges
    
    If the update is only a couple of lines tall, any tear will not be
    visible - so just ignore programming the wait into the GPU.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index a80a3c1..abb340a 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3005,7 +3005,7 @@ sna_wait_for_scanline(struct sna *sna,
        if (y2 > crtc->bounds.y2 - crtc->bounds.y1)
                y2 = crtc->bounds.y2 - crtc->bounds.y1;
        DBG(("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2));
-       if (y2 <= y1)
+       if (y2 <= y1 + 4)
                return false;
 
        full_height = y1 == 0 && y2 == crtc->bounds.y2 - crtc->bounds.y1;

commit 308f0208de59620190dd3cb65b3243d2e8a7bd87
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Mon Mar 18 15:04:22 2013 +0000

    sna: Reset operation state between glyphs
    
    We are not resetting sufficient state between operations as we presume
    that all callers of Composite() currently pass in a blank state. In the
    long run, we want to remove that burden and do a minimal initialisation.
    
    References: 
https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1156387
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 2f44113..3e2d79b 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -673,8 +673,6 @@ glyphs_slow(struct sna *sna,
        if (NO_GLYPHS_SLOW)
                return false;
 
-       memset(&tmp, 0, sizeof(tmp));
-
        DBG(("%s(op=%d, src=(%d, %d), nlist=%d,  dst=(%d, %d)+(%d, %d))\n",
             __FUNCTION__, op, src_x, src_y, nlist,
             list->xOff, list->yOff, dst->pDrawable->x, dst->pDrawable->y));
@@ -740,7 +738,7 @@ glyphs_slow(struct sna *sna,
                                                   y - glyph->info.y,
                                                   glyph->info.width,
                                                   glyph->info.height,
-                                                  &tmp))
+                                                  memset(&tmp, 0, 
sizeof(tmp))))
                                return false;
 
                        rects = REGION_RECTS(dst->pCompositeClip);

commit 4a37d57f9633bbd29f308239c1cd956767b277c0
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Mon Mar 18 15:00:01 2013 +0000

    sna: Add a pair of sanity checks before creating the redirection target
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 6a2438f..2e29d95 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1873,6 +1873,8 @@ sna_render_composite_redirect(struct sna *sna,
        int bpp = op->dst.pixmap->drawable.bitsPerPixel;
        struct kgem_bo *bo;
 
+       assert(t->real_bo == NULL);
+
 #if NO_REDIRECT
        return false;
 #endif
@@ -1954,6 +1956,7 @@ sna_render_composite_redirect(struct sna *sna,
                        t->real_bo = op->dst.bo;
                        t->real_damage = op->damage;
                        if (op->damage) {
+                               assert(!DAMAGE_IS_ALL(op->damage));
                                t->damage = sna_damage_create();
                                op->damage = &t->damage;
                        }

commit 28371a34fa83f70a7af3c8d3bfd6c7cef9e35073
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Mon Mar 18 14:49:58 2013 +0000

    sna: Skip processing an all-clipped-out glyph
    
    Along the slow path, skip all processing of glyphs that are not visible.
    This is important as the slow path handles the per-glyph redirection
    case, which is much more expensive.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index a244b97..13a5ce3 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -864,6 +864,21 @@ inline static bool is_clipped(const RegionRec *r,
                r->extents.y2 - r->extents.y1 != d->height);
 }
 
+inline static bool
+box_intersect(BoxPtr a, const BoxRec *b)
+{
+       if (a->x1 < b->x1)
+               a->x1 = b->x1;
+       if (a->x2 > b->x2)
+               a->x2 = b->x2;
+       if (a->y1 < b->y1)
+               a->y1 = b->y1;
+       if (a->y2 > b->y2)
+               a->y2 = b->y2;
+
+       return a->x1 < a->x2 && a->y1 < a->y2;
+}
+
 unsigned sna_cpu_detect(void);
 char *sna_cpu_features_to_string(unsigned features, char *line);
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index f654c1a..a2528f6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4727,21 +4727,6 @@ typedef void (*sna_copy_func)(DrawablePtr src, 
DrawablePtr dst, GCPtr gc,
                              RegionPtr region, int dx, int dy,
                              Pixel bitPlane, void *closure);
 
-inline static bool
-box_intersect(BoxPtr a, const BoxRec *b)
-{
-       if (a->x1 < b->x1)
-               a->x1 = b->x1;
-       if (a->x2 > b->x2)
-               a->x2 = b->x2;
-       if (a->y1 < b->y1)
-               a->y1 = b->y1;
-       if (a->y2 > b->y2)
-               a->y2 = b->y2;
-
-       return a->x1 < a->x2 && a->y1 < a->y2;
-}
-
 static RegionPtr
 sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
            int sx, int sy,
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 3b1cf37..2f44113 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -692,11 +692,21 @@ glyphs_slow(struct sna *sna,
                        GlyphPtr glyph = *glyphs++;
                        struct sna_glyph priv;
                        BoxPtr rects;
+                       BoxRec box;
                        int nrect;
 
                        if (!glyph_valid(glyph))
                                goto next_glyph;
 
+                       box.x1 = x - glyph->info.x;
+                       box.y1 = y - glyph->info.y;
+                       box.x2 = bound(box.x1, glyph->info.width);
+                       box.y2 = bound(box.y1, glyph->info.height);
+
+                       if (!box_intersect(&box,
+                                          &dst->pCompositeClip->extents))
+                               goto next_glyph;
+
                        priv = *sna_glyph(glyph);
                        if (priv.atlas == NULL) {
                                if (!glyph_cache(screen, &sna->render, glyph)) {
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 41322ad..540f3a6 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -41,21 +41,6 @@
 
 /* XXX Need to avoid using GTT fenced access for I915_TILING_Y on 855GM */
 
-static bool
-box_intersect(BoxPtr a, const BoxRec *b)
-{
-       if (a->x1 < b->x1)
-               a->x1 = b->x1;
-       if (a->x2 > b->x2)
-               a->x2 = b->x2;
-       if (a->y1 < b->y1)
-               a->y1 = b->y1;
-       if (a->y2 > b->y2)
-               a->y2 = b->y2;
-
-       return a->x1 < a->x2 && a->y1 < a->y2;
-}
-
 static inline bool upload_too_large(struct sna *sna, int width, int height)
 {
        return width * height * 4 > sna->kgem.max_upload_tile_size;
diff --git a/src/sna/sna_tiling.c b/src/sna/sna_tiling.c
index 019b50a..02ab59d 100644
--- a/src/sna/sna_tiling.c
+++ b/src/sna/sna_tiling.c
@@ -795,21 +795,6 @@ done:
        return ret;
 }
 
-static bool
-box_intersect(BoxPtr a, const BoxRec *b)
-{
-       if (a->x1 < b->x1)
-               a->x1 = b->x1;
-       if (a->x2 > b->x2)
-               a->x2 = b->x2;
-       if (a->y1 < b->y1)
-               a->y1 = b->y1;
-       if (a->y2 > b->y2)
-               a->y2 = b->y2;
-
-       return a->x1 < a->x2 && a->y1 < a->y2;
-}
-
 bool
 sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
                      PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, 
int16_t src_dy,

commit 16dac417c8049d65b3641e0f662865772faad61f
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Sun Mar 17 21:56:56 2013 +0000

    sna/dri: Fix stale Pixmap detection
    
    NB the back buffer is not associated with the Drawable and so has no
    pixmap field set. Hence comparing the front->pixmap against the
    back->pixmap was always rejecting the blit. All we can check is that
    front->pixmap corresponds with the current Drawable and so reject stale
    configuration.
    
    Reported-by: Jiri Slaby <jirisl...@gmail.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=47597
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 2d3a262..1a02449 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -884,8 +884,13 @@ can_blit(struct sna * sna,
        if (draw->type == DRAWABLE_PIXMAP)
                return true;
 
-       if (get_private(front)->pixmap != get_private(back)->pixmap)
+       if (get_private(front)->pixmap != get_drawable_pixmap(draw)) {
+               DBG(("%s: reject as front pixmap=%ld, but expecting 
pixmap=%ld\n",
+                    __FUNCTION__,
+                    get_private(front)->pixmap ? 
get_private(front)->pixmap->drawable.serialNumber : 0,
+                    get_drawable_pixmap(draw)->drawable.serialNumber));
                return false;
+       }
 
        clip = &((WindowPtr)draw)->clipList;
        w = clip->extents.x2 - draw->x;

commit 85213d5d450eec5696496128c1acecb5ca13c53b
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Sun Mar 17 21:42:48 2013 +0000

    sna: Don't remove the flush flag for userptr bo
    
    This flag is far too overload with meaning, but for now this prevents us
    attempting to call free() on a SHM segment.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index a01da88..e0d864d 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1752,7 +1752,8 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct 
kgem_bo *bo)
                        kgem_bo_move_to_snoop(kgem, bo);
                return;
        }
-       bo->flush = false;
+       if (!IS_USER_MAP(bo->map))
+               bo->flush = false;
 
        if (bo->scanout) {
                kgem_bo_move_to_scanout(kgem, bo);

commit c5b901a635a9c8c74017682d17cfcd93031907b4
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Sat Mar 16 10:54:51 2013 +0000

    sna/dri: Clear flush flag upon bo destroy
    
    Fixes sanity checks that we do not leak the flushing status, nor
    invoke an operation upon an unflushed bo.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 31e110e..a01da88 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1515,6 +1515,7 @@ inline static void kgem_bo_move_to_inactive(struct kgem 
*kgem,
        assert(!bo->io);
        assert(!bo->scanout);
        assert(!bo->snoop);
+       assert(!bo->flush);
        assert(!bo->needs_flush);
        assert(list_is_empty(&bo->vma));
        ASSERT_IDLE(kgem, bo->handle);
@@ -1635,6 +1636,7 @@ static void kgem_bo_move_to_scanout(struct kgem *kgem, 
struct kgem_bo *bo)
        assert(bo->refcnt == 0);
        assert(bo->scanout);
        assert(bo->delta);
+       assert(!bo->flush);
        assert(!bo->snoop);
        assert(!bo->io);
 
@@ -1750,6 +1752,7 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct 
kgem_bo *bo)
                        kgem_bo_move_to_snoop(kgem, bo);
                return;
        }
+       bo->flush = false;
 
        if (bo->scanout) {
                kgem_bo_move_to_scanout(kgem, bo);
@@ -1769,6 +1772,7 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct 
kgem_bo *bo)
 
        assert(list_is_empty(&bo->vma));
        assert(list_is_empty(&bo->list));
+       assert(bo->flush == false);
        assert(bo->snoop == false);
        assert(bo->io == false);
        assert(bo->scanout == false);
@@ -3554,6 +3558,7 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
                        assert(bo->scanout);
                        assert(bo->delta);
                        assert(!bo->purged);
+                       assert(!bo->flush);
 
                        if (size > num_pages(bo) || num_pages(bo) > 2*size)
                                continue;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 19fe1e3..f654c1a 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2442,6 +2442,9 @@ static inline struct sna_pixmap *
 sna_pixmap_mark_active(struct sna *sna, struct sna_pixmap *priv)
 {
        assert(priv->gpu_bo);
+       DBG(("%s: pixmap=%ld, handle=%u\n", __FUNCTION__,
+            priv->pixmap->drawable.serialNumber,
+            priv->gpu_bo->handle));
        return priv;
 }
 
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 127793f..2d3a262 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -884,6 +884,9 @@ can_blit(struct sna * sna,
        if (draw->type == DRAWABLE_PIXMAP)
                return true;
 
+       if (get_private(front)->pixmap != get_private(back)->pixmap)
+               return false;
+
        clip = &((WindowPtr)draw)->clipList;
        w = clip->extents.x2 - draw->x;
        h = clip->extents.y2 - draw->y;
@@ -919,6 +922,12 @@ sna_dri_copy_region(DrawablePtr draw,
        void (*copy)(struct sna *, DrawablePtr, RegionPtr,
                     struct kgem_bo *, struct kgem_bo *, bool) = sna_dri_copy;
 
+       DBG(("%s: pixmap=%ld, src=%u, dst=%u\n",
+            __FUNCTION__,
+            pixmap->drawable.serialNumber,
+            get_private(src_buffer)->bo->handle,
+            get_private(dst_buffer)->bo->handle));
+
        assert(get_private(src_buffer)->refcnt);
        assert(get_private(dst_buffer)->refcnt);
 
@@ -928,11 +937,11 @@ sna_dri_copy_region(DrawablePtr draw,
        assert(get_private(dst_buffer)->bo->refcnt);
        assert(get_private(dst_buffer)->bo->flush);
 
-       assert(sna_pixmap_from_drawable(draw)->flush);
-
        if (!can_blit(sna, draw, dst_buffer, src_buffer))
                return;
 
+       assert(sna_pixmap(pixmap)->flush);
+
        if (dst_buffer->attachment == DRI2BufferFrontLeft) {
                dst = sna_pixmap_get_bo(pixmap);
                copy = (void *)sna_dri_copy_to_front;

commit 45d20e9a65bec8d962a4ec20ee35079935f71b91
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Mar 14 22:09:38 2013 +0000

    sna: Add an LLC path for creating snoopable buffers
    
    As with LLC we do not actually need to track snoopable as a separate
    cache state.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 34ea212..31e110e 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -5005,6 +5005,42 @@ create_snoopable_buffer(struct kgem *kgem, unsigned 
alloc)
        struct kgem_buffer *bo;
        uint32_t handle;
 
+       if (kgem->has_llc) {
+               struct kgem_bo *old;
+
+               bo = buffer_alloc();
+               if (bo == NULL)
+                       return NULL;
+
+               old = search_linear_cache(kgem, alloc,
+                                        CREATE_INACTIVE | CREATE_CPU_MAP | 
CREATE_EXACT);
+               if (old) {
+                       init_buffer_from_bo(bo, old);
+               } else {
+                       handle = gem_create(kgem->fd, alloc);
+                       if (handle == 0) {
+                               free(bo);
+                               return NULL;
+                       }
+
+                       debug_alloc(kgem, alloc);
+                       __kgem_bo_init(&bo->base, handle, alloc);
+                       DBG(("%s: created CPU (LLC) handle=%d for buffer, size 
%d\n",
+                            __FUNCTION__, bo->base.handle, alloc));
+               }
+
+               assert(bo->base.refcnt == 1);
+               assert(bo->mmapped == true);
+               assert(bo->need_io == false);
+
+               bo->mem = kgem_bo_map__cpu(kgem, &bo->base);
+               if (bo->mem != NULL)
+                       return bo;
+
+               bo->base.refcnt = 0; /* for valgrind */
+               kgem_bo_free(kgem, &bo->base);
+       }
+
        if (kgem->has_cacheing) {
                struct kgem_bo *old;
 

commit 94cb10c3f2b9bbb6ae3c76faebe9fc88691224a9
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Mar 14 22:02:09 2013 +0000

    sna/gen5+: Add missing float casts in computation of scaled src offsets
    
    Without the casts, the division ends up as 0 rather than the fractional
    offset into the texture.
    
    The casts were missed in the claimed fix:
    
    commit 89038ddb96aabc4bc1f04402b2aca0ce546e8bf3
    Author: Chris Wilson <ch...@chris-wilson.co.uk>
    Date:   Thu Feb 28 14:35:54 2013 +0000
    
        sna/video: Correct scaling of source offsets
    
    Reported-by: Roman Elshin <roman.els...@gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=62343
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 67f7b64..e40a1b7 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1379,10 +1379,10 @@ gen4_render_video(struct sna *sna,
 #endif
 
        src_scale_x = (float)src_width / dst_width / frame->width;
-       src_offset_x = frame->src.x1 / frame->width - dstRegion->extents.x1 * 
src_scale_x;
+       src_offset_x = (float)frame->src.x1 / frame->width - 
dstRegion->extents.x1 * src_scale_x;
 
        src_scale_y = (float)src_height / dst_height / frame->height;
-       src_offset_y = frame->src.y1 / frame->height - dstRegion->extents.y1 * 
src_scale_y;
+       src_offset_y = (float)frame->src.y1 / frame->height - 
dstRegion->extents.y1 * src_scale_y;
 
        box = REGION_RECTS(dstRegion);
        nbox = REGION_NUM_RECTS(dstRegion);
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 8c8a996..8b50d22 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1363,10 +1363,10 @@ gen5_render_video(struct sna *sna,
 #endif
 
        src_scale_x = (float)src_width / dst_width / frame->width;
-       src_offset_x = frame->src.x1 / frame->width - dstRegion->extents.x1 * 
src_scale_x;
+       src_offset_x = (float)frame->src.x1 / frame->width - 
dstRegion->extents.x1 * src_scale_x;
 
        src_scale_y = (float)src_height / dst_height / frame->height;
-       src_offset_y = frame->src.y1 / frame->height - dstRegion->extents.y1 * 
src_scale_y;
+       src_offset_y = (float)frame->src.y1 / frame->height - 
dstRegion->extents.y1 * src_scale_y;
 
        box = REGION_RECTS(dstRegion);
        nbox = REGION_NUM_RECTS(dstRegion);
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 8d15bd8..64eccc5 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -1651,10 +1651,10 @@ gen6_render_video(struct sna *sna,
 #endif
 
        src_scale_x = (float)src_width / dst_width / frame->width;
-       src_offset_x = frame->src.x1 / frame->width - dstRegion->extents.x1 * 
src_scale_x;
+       src_offset_x = (float)frame->src.x1 / frame->width - 
dstRegion->extents.x1 * src_scale_x;
 
        src_scale_y = (float)src_height / dst_height / frame->height;
-       src_offset_y = frame->src.y1 / frame->height - dstRegion->extents.y1 * 
src_scale_y;
+       src_offset_y = (float)frame->src.y1 / frame->height - 
dstRegion->extents.y1 * src_scale_y;
 
        box = REGION_RECTS(dstRegion);
        nbox = REGION_NUM_RECTS(dstRegion);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 4453797..80fa872 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -1792,17 +1792,39 @@ gen7_render_video(struct sna *sna,
        pix_yoff = 0;
 #endif
 
+       DBG(("%s: src=(%d, %d)x(%d, %d); frame=(%dx%d), dst=(%dx%d)\n",
+            __FUNCTION__,
+            frame->src.x1, frame->src.y1,
+            src_width, src_height,
+            dst_width, dst_height,
+            frame->width, frame->height));
+
        src_scale_x = (float)src_width / dst_width / frame->width;
-       src_offset_x = frame->src.x1 / frame->width - dstRegion->extents.x1 * 
src_scale_x;
+       src_offset_x = (float)frame->src.x1 / frame->width - 
dstRegion->extents.x1 * src_scale_x;
 
        src_scale_y = (float)src_height / dst_height / frame->height;
-       src_offset_y = frame->src.y1 / frame->height - dstRegion->extents.y1 * 
src_scale_y;
+       src_offset_y = (float)frame->src.y1 / frame->height - 
dstRegion->extents.y1 * src_scale_y;
+
+       DBG(("%s: scale=(%f, %f), offset=(%f, %f)\n",
+            __FUNCTION__,
+            src_scale_x, src_scale_y,
+            src_offset_x, src_offset_y));
 
        box = REGION_RECTS(dstRegion);
        nbox = REGION_NUM_RECTS(dstRegion);
        while (nbox--) {
                BoxRec r;
 
+               DBG(("%s: dst=(%d, %d), (%d, %d) + (%d, %d); src=(%f, %f), (%f, 
%f)\n",
+                    __FUNCTION__,
+                    box->x1, box->y1,
+                    box->x2, box->y2,
+                    pix_xoff, pix_yoff,
+                    box->x1 * src_scale_x + src_offset_x,
+                    box->y1 * src_scale_y + src_offset_y,
+                    box->x2 * src_scale_x + src_offset_x,
+                    box->y2 * src_scale_y + src_offset_y));
+
                r.x1 = box->x1 + pix_xoff;
                r.x2 = box->x2 + pix_xoff;
                r.y1 = box->y1 + pix_yoff;

commit dad50881d545da665191c6681f2acd0ebc3ddbfc
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Mar 14 14:53:13 2013 +0000

    sna: Consider placement hints when choosing userptr read path
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index dfb160b..19fe1e3 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -13468,7 +13468,8 @@ static int sna_create_gc(GCPtr gc)
 static bool
 sna_get_image_blt(DrawablePtr drawable,
                  RegionPtr region,
-                 char *dst)
+                 char *dst,
+                 unsigned flags)
 {
        PixmapPtr pixmap = get_drawable_pixmap(drawable);
        struct sna_pixmap *priv = sna_pixmap(pixmap);
@@ -13477,9 +13478,6 @@ sna_get_image_blt(DrawablePtr drawable,
        bool ok = false;
        int pitch;
 
-       if (!USE_USERPTR_DOWNLOADS)
-               return false;
-
        if (priv == NULL)
                return false;
 
@@ -13503,7 +13501,10 @@ sna_get_image_blt(DrawablePtr drawable,
                return true;
        }
 
-       if (!sna->kgem.has_userptr)
+       if (!sna->kgem.has_userptr || !USE_USERPTR_DOWNLOADS)
+               return false;
+
+       if (flags & (MOVE_WHOLE_HINT | MOVE_INPLACE_HINT))
                return false;
 
        if (priv->gpu_damage == NULL)
@@ -13575,14 +13576,15 @@ sna_get_image(DrawablePtr drawable,
                drawable->bitsPerPixel >= 8 &&
                PM_IS_SOLID(drawable, mask);
 
-       if (can_blt && sna_get_image_blt(drawable, &region, dst))
-               return;
-
        flags = MOVE_READ;
        if ((w | h) == 1)
                flags |= MOVE_INPLACE_HINT;
        if (w == drawable->width)
                flags |= MOVE_WHOLE_HINT;
+
+       if (can_blt && sna_get_image_blt(drawable, &region, dst, flags))
+               return;
+
        if (!sna_drawable_move_region_to_cpu(drawable, &region, flags))
                return;
 

commit 11e2802528aed4ef9ffc8b75045c72ac641e54b1
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Mar 14 14:42:25 2013 +0000

    sna: Add handle info to sync DBG
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 538231f..34ea212 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4769,14 +4769,17 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
 
 void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo)
 {
+       DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
        assert(bo->proxy == NULL);
        kgem_bo_submit(kgem, bo);
 
        if (bo->domain != DOMAIN_CPU) {
                struct drm_i915_gem_set_domain set_domain;
 
-               DBG(("%s: SYNC: needs_flush? %d, domain? %d, busy? %d\n", 
__FUNCTION__,
-                    bo->needs_flush, bo->domain, __kgem_busy(kgem, 
bo->handle)));
+               DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? 
%d\n",
+                    __FUNCTION__, bo->handle,
+                    bo->needs_flush, bo->domain,
+                    __kgem_busy(kgem, bo->handle)));
 
                VG_CLEAR(set_domain);
                set_domain.handle = bo->handle;
@@ -4792,6 +4795,7 @@ void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo 
*bo)
 
 void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write)
 {
+       DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
        assert(bo->proxy == NULL);
 
        if (write || bo->needs_flush)
@@ -4800,8 +4804,10 @@ void kgem_bo_sync__cpu_full(struct kgem *kgem, struct 
kgem_bo *bo, bool write)
        if (bo->domain != DOMAIN_CPU) {
                struct drm_i915_gem_set_domain set_domain;
 
-               DBG(("%s: SYNC: needs_flush? %d, domain? %d, busy? %d\n", 
__FUNCTION__,
-                    bo->needs_flush, bo->domain, __kgem_busy(kgem, 
bo->handle)));
+               DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? 
%d\n",
+                    __FUNCTION__, bo->handle,
+                    bo->needs_flush, bo->domain,
+                    __kgem_busy(kgem, bo->handle)));
 
                VG_CLEAR(set_domain);
                set_domain.handle = bo->handle;
@@ -4818,14 +4824,17 @@ void kgem_bo_sync__cpu_full(struct kgem *kgem, struct 
kgem_bo *bo, bool write)
 
 void kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo)
 {
+       DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
        assert(bo->proxy == NULL);
        kgem_bo_submit(kgem, bo);
 
        if (bo->domain != DOMAIN_GTT) {
                struct drm_i915_gem_set_domain set_domain;
 
-               DBG(("%s: SYNC: needs_flush? %d, domain? %d, busy? %d\n", 
__FUNCTION__,
-                    bo->needs_flush, bo->domain, __kgem_busy(kgem, 
bo->handle)));
+               DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? 
%d\n",
+                    __FUNCTION__, bo->handle,
+                    bo->needs_flush, bo->domain,
+                    __kgem_busy(kgem, bo->handle)));
 
                VG_CLEAR(set_domain);
                set_domain.handle = bo->handle;

commit 20832494be06da9ebc4801647521f95e092188fc
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Mar 14 14:03:00 2013 +0000

    sna: Use userptr downloads for incomplete GPU damaged pixmaps
    
    If the pixmap is not wholly damaged, but still contains the region to be
    read, then use userptr (if available).
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ea7dc7a..dfb160b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -13506,8 +13506,16 @@ sna_get_image_blt(DrawablePtr drawable,
        if (!sna->kgem.has_userptr)
                return false;
 
-       if (!DAMAGE_IS_ALL(priv->gpu_damage) ||
-           !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
+       if (priv->gpu_damage == NULL)
+               return false;
+
+       assert(priv->gpu_bo);
+       if (!__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))
+               return false;
+
+       if (!DAMAGE_IS_ALL(priv->gpu_damage) &&
+           !sna_damage_contains_box__no_reduce(priv->gpu_damage,
+                                               &region->extents))
                return false;
 
        DBG(("%s: download through a temporary map\n", __FUNCTION__));

commit 92023f39a9c8897e5a978f44b7970773b118f628
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Mar 14 09:42:37 2013 +0000

    sna: Add a few more assertions to track userptr through the caches
    
    i.e. make sure they don't end up in any caches.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 8d3e9df..538231f 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1514,6 +1514,7 @@ inline static void kgem_bo_move_to_inactive(struct kgem 
*kgem,
        assert(!bo->proxy);
        assert(!bo->io);
        assert(!bo->scanout);
+       assert(!bo->snoop);
        assert(!bo->needs_flush);
        assert(list_is_empty(&bo->vma));
        ASSERT_IDLE(kgem, bo->handle);
@@ -1647,6 +1648,9 @@ static void kgem_bo_move_to_scanout(struct kgem *kgem, 
struct kgem_bo *bo)
 
 static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo)
 {
+       assert(bo->reusable);
+       assert(!bo->flush);
+       assert(!bo->needs_flush);
        assert(bo->refcnt == 0);
        assert(bo->exec == NULL);
 
@@ -1738,14 +1742,12 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct 
kgem_bo *bo)
 
        if (bo->snoop && !bo->flush) {
                DBG(("%s: handle=%d is snooped\n", __FUNCTION__, bo->handle));
-               assert(!bo->flush);
+               assert(bo->reusable);
                assert(list_is_empty(&bo->list));
                if (bo->exec == NULL && bo->rq && !__kgem_busy(kgem, 
bo->handle))
                        __kgem_bo_clear_busy(bo);
-               if (bo->rq == NULL) {
-                       assert(!bo->needs_flush);
+               if (bo->rq == NULL)
                        kgem_bo_move_to_snoop(kgem, bo);
-               }
                return;
        }
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ead4692..ea7dc7a 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4463,6 +4463,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
                                                            box, n, COPY_LAST);
 
                                kgem_bo_sync__cpu(&sna->kgem, src_bo);
+                               assert(src_bo->rq == NULL);
                                kgem_bo_destroy(&sna->kgem, src_bo);
                        }
 
@@ -13534,6 +13535,7 @@ sna_get_image_blt(DrawablePtr drawable,
                                            COPY_LAST);


-- 
To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/e1uigp7-0006ij...@vasks.debian.org

Reply via email to