man/intel.man         |   13 
 src/intel_list.h      |    7 
 src/intel_options.c   |    1 
 src/intel_options.h   |    1 
 src/sna/gen6_render.c |    3 
 src/sna/gen7_render.c |    3 
 src/sna/gen8_render.c |    3 
 src/sna/kgem.c        |  143 +++++--
 src/sna/sna.h         |    2 
 src/sna/sna_accel.c   |    5 
 src/sna/sna_display.c |  248 ++++++++-----
 src/sna/sna_dri2.c    |  941 +++++++++++++++++++++++++-------------------------
 src/sna/sna_driver.c  |   15 
 src/sna/sna_render.c  |    6 
 src/uxa/intel_hwmc.c  |    2 
 15 files changed, 792 insertions(+), 601 deletions(-)

New commits:
commit ef859c807a4bfad7c8a01a1d63f354f3ef310db5
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Mon Oct 19 13:07:13 2015 +0100

    sna: Use the new context param for report GTT size
    
    Since get_aperture_ioctl reports the global GTT size and this may
    differ with the per-process GTT size used by execbuffer, query the
    per-process GTT size instead.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index bbe2092..156ebc9 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1822,12 +1822,50 @@ no_context_switch(struct kgem *kgem, int new_mode)
        (void)new_mode;
 }
 
-void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
+static uint64_t get_gtt_size(int fd)
 {
        struct drm_i915_gem_get_aperture aperture;
+       struct local_i915_gem_context_param {
+               uint32_t context;
+               uint32_t size;
+               uint64_t param;
+#define LOCAL_CONTEXT_PARAM_BAN_PERIOD 0x1
+#define LOCAL_CONTEXT_PARAM_NO_ZEROMAP 0x2
+#define LOCAL_CONTEXT_PARAM_GTT_SIZE   0x3
+               uint64_t value;
+       } p;
+#define LOCAL_I915_GEM_CONTEXT_GETPARAM       0x34
+#define LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + 
LOCAL_I915_GEM_CONTEXT_GETPARAM, struct local_i915_gem_context_param)
+
+       memset(&aperture, 0, sizeof(aperture));
+
+       memset(&p, 0, sizeof(p));
+       p.param = LOCAL_CONTEXT_PARAM_GTT_SIZE;
+       if (drmIoctl(fd, LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM, &p) == 0)
+               aperture.aper_size = p.value;
+       if (aperture.aper_size == 0)
+               (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+       if (aperture.aper_size == 0)
+               aperture.aper_size = 64*1024*1024;
+
+       DBG(("%s: aperture size %lld, available now %lld\n",
+            __FUNCTION__,
+            (long long)aperture.aper_size,
+            (long long)aperture.aper_available_size));
+
+       /* clamp aperture to uint32_t for simplicity */
+       if (aperture.aper_size > 0xc0000000)
+               aperture.aper_size = 0xc0000000;
+
+       return aperture.aper_size;
+}
+
+void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
+{
        size_t totalram;
        unsigned half_gpu_max;
        unsigned int i, j;
+       uint64_t gtt_size;
 
        DBG(("%s: fd=%d, gen=%d\n", __FUNCTION__, fd, gen));
 
@@ -1979,23 +2017,10 @@ void kgem_init(struct kgem *kgem, int fd, struct 
pci_device *dev, unsigned gen)
             !DBG_NO_CPU && (kgem->has_llc | kgem->has_userptr | 
kgem->has_caching),
             kgem->has_llc, kgem->has_caching, kgem->has_userptr));
 
-       VG_CLEAR(aperture);
-       aperture.aper_size = 0;
-       (void)do_ioctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
-       if (aperture.aper_size == 0)
-               aperture.aper_size = 64*1024*1024;
-
-       DBG(("%s: aperture size %lld, available now %lld\n",
-            __FUNCTION__,
-            (long long)aperture.aper_size,
-            (long long)aperture.aper_available_size));
-
-       /* clamp aperture to uint32_t for simplicity */
-       if (aperture.aper_size > 0xc0000000)
-               aperture.aper_size = 0xc0000000;
-       kgem->aperture_total = aperture.aper_size;
-       kgem->aperture_high = aperture.aper_size * 3/4;
-       kgem->aperture_low = aperture.aper_size * 1/3;
+       gtt_size = get_gtt_size(fd);
+       kgem->aperture_total = gtt_size;
+       kgem->aperture_high = gtt_size * 3/4;
+       kgem->aperture_low = gtt_size * 1/3;
        if (gen < 033) {
                /* Severe alignment penalties */
                kgem->aperture_high /= 2;
@@ -2008,9 +2033,8 @@ void kgem_init(struct kgem *kgem, int fd, struct 
pci_device *dev, unsigned gen)
        kgem->aperture_mappable = 256 * 1024 * 1024;
        if (dev != NULL)
                kgem->aperture_mappable = agp_aperture_size(dev, gen);
-       if (kgem->aperture_mappable == 0 ||
-           kgem->aperture_mappable > aperture.aper_size)
-               kgem->aperture_mappable = aperture.aper_size;
+       if (kgem->aperture_mappable == 0 || kgem->aperture_mappable > gtt_size)
+               kgem->aperture_mappable = gtt_size;
        DBG(("%s: aperture mappable=%d [%d MiB]\n", __FUNCTION__,
             kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024)));
 

commit 3656bcf01e78554aaeafc11ecebb0caf7dd12713
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Mon Oct 19 09:34:43 2015 +0100

    sna: Manually clear the GPU bo needs_flush flag after doing an explicit 
flush
    
    The kernel often gets confused and fails to flush the bo itself, so lets
    just pretend it worked.
    
    Reported-by: Jiri Slaby <jirisl...@gmail.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=70461#c127
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index bb1f70b..bbe2092 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -6752,6 +6752,7 @@ void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
                        DBG(("%s: sync: GPU hang detected\n", __FUNCTION__));
                        kgem_throttle(kgem);
                }
+               bo->needs_flush = false;
                kgem_bo_retire(kgem, bo);
                bo->domain = DOMAIN_GTT;
                bo->gtt_dirty = true;
@@ -6964,6 +6965,7 @@ void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo 
*bo)
                        DBG(("%s: sync: GPU hang detected\n", __FUNCTION__));
                        kgem_throttle(kgem);
                }
+               bo->needs_flush = false;
                kgem_bo_retire(kgem, bo);
                bo->domain = DOMAIN_CPU;
        }
@@ -7004,6 +7006,7 @@ void kgem_bo_sync__cpu_full(struct kgem *kgem, struct 
kgem_bo *bo, bool write)
                        kgem_throttle(kgem);
                }
                if (write) {
+                       bo->needs_flush = false;
                        kgem_bo_retire(kgem, bo);
                        bo->domain = DOMAIN_CPU;
                } else {
@@ -7040,6 +7043,7 @@ void kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo 
*bo)
                        DBG(("%s: sync: GPU hang detected\n", __FUNCTION__));
                        kgem_throttle(kgem);
                }
+               bo->needs_flush = false;
                kgem_bo_retire(kgem, bo);
                bo->domain = DOMAIN_GTT;
                bo->gtt_dirty = true;

commit 6861391ff34eff423974a73c46cf0b186a6cb335
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Tue Oct 13 12:22:46 2015 +0100

    sna: Make sure that cached upload proxies are marked as all-damaged
    
    It should only be the case that we create the upload proxy in this case,
    but it ensures that the code remains self-consistent if we force the
    all-damage reduction.
    
    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 89267a3..d8b7756 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -553,6 +553,7 @@ static struct kgem_bo *upload(struct sna *sna,
                        assert(priv->gpu_damage == NULL);
                        assert(priv->gpu_bo == NULL);
                        assert(bo->proxy != NULL);
+                       sna_damage_all(&priv->cpu_damage, pixmap);
                        kgem_proxy_bo_attach(bo, &priv->gpu_bo);
                }
        }
@@ -1261,6 +1262,7 @@ sna_render_picture_extract(struct sna *sna,
                        assert(priv->gpu_damage == NULL);
                        assert(priv->gpu_bo == NULL);
                        assert(bo->proxy != NULL);
+                       sna_damage_all(&priv->cpu_damage, pixmap);
                        kgem_proxy_bo_attach(bo, &priv->gpu_bo);
                }
        }

commit 6224814b85e8aed75854192ec27aa06163e76d94
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Tue Oct 13 12:20:33 2015 +0100

    sna: Handle proxy objects in undo assertions
    
    Note that we may try to clear a batch containing a proxy object, in
    which case the proxy has a dummy exec entry - so we need to be careful
    in making our assertions.
    
    Reported-by: Laszlo Valko <va...@linux.karinthy.hu>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92447
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b975bfc..bb1f70b 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2807,7 +2807,7 @@ void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo)
        DBG(("%s: only handle in batch, discarding last operations for 
handle=%d\n",
             __FUNCTION__, bo->handle));
 
-       assert(bo->exec == &kgem->exec[0]);
+       assert(bo->exec == &_kgem_dummy_exec || bo->exec == &kgem->exec[0]);
        assert(kgem->exec[0].handle == bo->handle);
        assert(RQ(bo->rq) == kgem->next_request);
 
@@ -2835,16 +2835,23 @@ void kgem_bo_pair_undo(struct kgem *kgem, struct 
kgem_bo *a, struct kgem_bo *b)
 
        if (a == NULL || b == NULL)
                return;
+       assert(a != b);
        if (a->exec == NULL || b->exec == NULL)
                return;
 
-       DBG(("%s: only handles in batch, discarding last operations for 
handle=%d and handle=%d\n",
-            __FUNCTION__, a->handle, b->handle));
+       DBG(("%s: only handles in batch, discarding last operations for 
handle=%d (index=%d) and handle=%d (index=%d)\n",
+            __FUNCTION__,
+            a->handle, a->proxy ? -1 : a->exec - kgem->exec,
+            b->handle, b->proxy ? -1 : b->exec - kgem->exec));
 
-       assert(a->exec == &kgem->exec[0] || a->exec == &kgem->exec[1]);
+       assert(a->exec == &_kgem_dummy_exec ||
+              a->exec == &kgem->exec[0] ||
+              a->exec == &kgem->exec[1]);
        assert(a->handle == kgem->exec[0].handle || a->handle == 
kgem->exec[1].handle);
        assert(RQ(a->rq) == kgem->next_request);
-       assert(b->exec == &kgem->exec[0] || b->exec == &kgem->exec[1]);
+       assert(b->exec == &_kgem_dummy_exec ||
+              b->exec == &kgem->exec[0] ||
+              b->exec == &kgem->exec[1]);
        assert(b->handle == kgem->exec[0].handle || b->handle == 
kgem->exec[1].handle);
        assert(RQ(b->rq) == kgem->next_request);
 

commit df72bc57610bb2f58eec9801820ea11628b244eb
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Fri Oct 9 15:40:58 2015 +0100

    sna: Avoid truncating the cursor when scaling up
    
    The affine_blt walks the destination image sampling from the source, so
    we need to walk all the output pixels and not the source size.
    
    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 554c270..a617218 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -5405,14 +5405,14 @@ static struct sna_cursor *__sna_get_cursor(struct sna 
*sna, xf86CrtcPtr crtc)
                        if (transformed) {
                                affine_blt(image, cursor->image, 32,
                                           0, 0, width, height, size * 4,
-                                          0, 0, width, height, size * 4,
+                                          0, 0, size, size, size * 4,
                                           &to_sna_crtc(crtc)->cursor_to_fb);
                                image = cursor->image;
                        }
                } else if (transformed) {
                        affine_blt(argb, cursor->image, 32,
                                   0, 0, width, height, width * 4,
-                                  0, 0, width, height, size * 4,
+                                  0, 0, size, size, size * 4,
                                   &to_sna_crtc(crtc)->cursor_to_fb);
                        image = cursor->image;
                } else

commit 5793183c8247b42baa3c4577a3d84d554d589160
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Fri Oct 9 15:17:58 2015 +0100

    sna: Compute rotation cursor transformation
    
    A confusion over the use of marking when we need to compute a
    transformed cursor image using pixman version when we need to compute
    transformed cursor coordinates meant that we failed to compute the
    required transformation after simply rotating the monitor.
    
    Should fix the regression from
    commit bbbcc4101ca01a5c8bec5169e47d703dd742494b
    Author: Chris Wilson <ch...@chris-wilson.co.uk>
    Date:   Fri Sep 18 12:17:07 2015 +0100
    
        sna: Apply cursor hotspot transformation
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
    References: https://bugs.archlinux.org/task/46606

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index a763d18..554c270 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -5340,17 +5340,17 @@ static struct sna_cursor *__sna_get_cursor(struct sna 
*sna, xf86CrtcPtr crtc)
 
                pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer, &box);
                size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1);
-
-               RRTransformCompute(0, 0,
-                                  sna->cursor.ref->bits->width,
-                                  sna->cursor.ref->bits->height,
-                                  crtc->rotation, &crtc->transform,
-                                  &cursor_to_fb,
-                                  &to_sna_crtc(crtc)->cursor_to_fb,
-                                  &to_sna_crtc(crtc)->fb_to_cursor);
        } else
                size = sna->cursor.size;
 
+       if (crtc->transform_in_use)
+                RRTransformCompute(0, 0, size, size,
+                                   crtc->rotation,
+                                   crtc->transformPresent ? &crtc->transform : 
NULL,
+                                   &cursor_to_fb,
+                                   &to_sna_crtc(crtc)->cursor_to_fb,
+                                   &to_sna_crtc(crtc)->fb_to_cursor);
+
        cursor = to_sna_crtc(crtc)->cursor;
        if (cursor && cursor->alloc < 4*size*size)
                cursor = NULL;
@@ -5726,18 +5726,18 @@ sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
                        int yhot = sna->cursor.ref->bits->yhot;
                        struct pict_f_vector v, hot;
 
-                       v.v[0] = (x + xhot) + 0.5;
-                       v.v[1] = (y + yhot) + 0.5;
-                       v.v[2] = 1;
+                       v.v[0] = x + xhot + .5;
+                       v.v[1] = y + yhot + .5;
+                       v.v[2] = 1.;
                        pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, 
&v);
 
-                       hot.v[0] = xhot + .5;
-                       hot.v[1] = yhot + .5;
+                       hot.v[0] = xhot;
+                       hot.v[1] = yhot;
                        hot.v[2] = 1.;
                        pixman_f_transform_point(&sna_crtc->fb_to_cursor, &hot);
 
-                       arg.x = floor(v.v[0]) - floor(hot.v[0]);
-                       arg.y = floor(v.v[1]) - floor(hot.v[1]);
+                       arg.x = floor(v.v[0] - hot.v[0]);
+                       arg.y = floor(v.v[1] - hot.v[1]);
                } else {
                        arg.x = x - crtc->x;
                        arg.y = y - crtc->y;

commit 4e668dd19ca402321091311fc6c2dd5cd9c28f23
Author: Robert Ancell <robert.anc...@canonical.com>
Date:   Fri Oct 2 10:43:10 2015 +0100

    uxa: Add missing const to string to stop compiler warning

diff --git a/src/uxa/intel_hwmc.c b/src/uxa/intel_hwmc.c
index 829cb8e..7854060 100644
--- a/src/uxa/intel_hwmc.c
+++ b/src/uxa/intel_hwmc.c
@@ -193,7 +193,7 @@ Bool intel_xvmc_adaptor_init(ScreenPtr pScreen)
        intel_screen_private *intel = intel_get_screen_private(scrn);
        struct pci_device *pci;
        static XF86MCAdaptorRec *pAdapt;
-       char *name;
+       const char *name;
        char buf[64];
 
        if (!intel->XvMCEnabled)

commit 096ddef22d6c57198a424eef00845dc7302b0cfe
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Thu Oct 1 09:47:59 2015 +0100

    sna: Indicate when we expect to call RRGetInfo during discovery
    
    Continuing the udevless saga where we query for topology changes on
    calls to RRGetInfo() and so where we cannot call RRGetInfo() ourselves
    on discovering the changes (to facilitate hotplug). The next step is
    explicitly prevent the recursive call.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=91929#c10
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 6c4d179..7592f7b 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -442,7 +442,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
 bool sna_mode_fake_init(struct sna *sna, int num_fake);
 bool sna_mode_wants_tear_free(struct sna *sna);
 void sna_mode_adjust_frame(struct sna *sna, int x, int y);
-extern void sna_mode_discover(struct sna *sna);
+extern void sna_mode_discover(struct sna *sna, bool tell);
 extern void sna_mode_check(struct sna *sna);
 extern bool sna_mode_disable(struct sna *sna);
 extern void sna_mode_enable(struct sna *sna);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 6db379d..a763d18 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2641,7 +2641,7 @@ error:
        sna_crtc->cursor_transform = saved_cursor_transform;
        sna_crtc->hwcursor = saved_hwcursor;
        sna_crtc->bo = saved_bo;
-       sna_mode_discover(sna);
+       sna_mode_discover(sna, true);
        return FALSE;
 }
 
@@ -4829,7 +4829,7 @@ output_check_status(struct sna *sna, struct sna_output 
*output)
        return output->status == status;
 }
 
-void sna_mode_discover(struct sna *sna)
+void sna_mode_discover(struct sna *sna, bool tell)
 {
        ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
        xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
@@ -4939,7 +4939,7 @@ void sna_mode_discover(struct sna *sna)
         * Note this could recurse once from udevless RRGetInfo() probes,
         * but only once.
         */
-       if (changed)
+       if (changed && tell)
                RRGetInfo(screen, TRUE);
 }
 
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 539093e..8cbabb0 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -780,7 +780,7 @@ sna_handle_uevents(int fd, void *closure)
                     __FUNCTION__, sna->scrn->vtSema));
 
                if (sna->scrn->vtSema) {
-                       sna_mode_discover(sna);
+                       sna_mode_discover(sna, true);
                        sna_mode_check(sna);
                } else
                        sna->flags |= SNA_REPROBE;
@@ -893,7 +893,7 @@ sna_randr_getinfo(ScreenPtr screen, Rotation *rotations)
        DBG(("%s()\n", __FUNCTION__));
 
        if (!sna_uevent_poll(sna))
-               sna_mode_discover(sna);
+               sna_mode_discover(sna, false);
 
        return sna->mode.rrGetInfo(screen, rotations);
 }
@@ -1222,7 +1222,7 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL)
 
        if (sna->flags & SNA_REPROBE) {
                DBG(("%s: reporting deferred hotplug event\n", __FUNCTION__));
-               sna_mode_discover(sna);
+               sna_mode_discover(sna, true);
        }
 
        sna_set_desired_mode(sna);

commit 0d3e1d3b2e0d82261e367ebba5992c89c429b7c7
Author: Olivier Fourdan <ofour...@redhat.com>
Date:   Tue Sep 29 13:18:58 2015 +0200

    man: Fix discrepancy in man page for ZaphodHeads
    
    Signed-off-by: Olivier Fourdan <ofour...@redhat.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92179
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/man/intel.man b/man/intel.man
index aa0eb6f..e1b7fb9 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -343,13 +343,13 @@ Default: 0
 .BI "Option \*qZaphodHeads\*q \*q" string \*q
 .IP
 Specify the randr output(s) to use with zaphod mode for a particular driver
-instance.  If you this option you must use it with all instances of the
+instance.  If you set this option you must use it with all instances of the
 driver
 .br
 For example:
 .B
 Option \*qZaphodHeads\*q \*qLVDS1,VGA1\*q
-will assign xrandr outputs LVDS1 and VGA0 to this instance of the driver.
+will assign xrandr outputs LVDS1 and VGA1 to this instance of the driver.
 
 .SH OUTPUT CONFIGURATION
 On 830M and better chipsets, the driver supports runtime configuration of

commit 679ee12079a7d2682d41506b81973c7c7d4fa1d8
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Sun Sep 27 19:05:26 2015 +0100

    sna: Prevent infinite recursion on udevless RRGetInfo()
    
    As summarised by Mark Kettenis:
    
        Unfortunately commit 2c08d72393e4c8ddf5926571b087459aaa225cb1 that
        was made to resolve this bug introduced infinite recursion if
        polling udev for events fails (which is always the case on systems
        without udev).  The scenario is as follows:
    
        1. The server calls RRGetInfo().
        2. RRGetInfo() calls sna_randr_getinfo()
        3. sna_randr_getinfo() calls sna_uevent_poll(), which returns false
        4. sna_randr_getinfo() calls sna_mode_discover()
        5. sna_mode_discover() calls RRGetInfo()
    
        and we jump straight back to step 2, until we run out of stack
        space and crash
    
    Reported-by: Mark Kettenis <kette...@openbsd.org>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91929#c8
    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 1b1a125..6db379d 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4900,6 +4900,7 @@ void sna_mode_discover(struct sna *sna)
                                DBG(("%s: output %s (id=%d), changed state, 
reprobing\n",
                                     __FUNCTION__, output->name, 
sna_output->id));
                                sna_output->last_detect = 0;
+                               changed |= 4;
                        }
                        continue;
                }
@@ -4918,7 +4919,8 @@ void sna_mode_discover(struct sna *sna)
                changed |= 2;
        }
 
-       if (changed) {
+       /* Have the list of available outputs been updated? */
+       if (changed & 3) {
                DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__));
 
                sna_mode_set_primary(sna);
@@ -4933,8 +4935,12 @@ void sna_mode_discover(struct sna *sna)
                xf86RandR12TellChanged(screen);
        }
 
-       RRGetInfo(screen, TRUE);
-       RRTellChanged(screen);
+       /* If anything has changed, refresh the RandR information.
+        * Note this could recurse once from udevless RRGetInfo() probes,
+        * but only once.
+        */
+       if (changed)
+               RRGetInfo(screen, TRUE);
 }
 
 /* Since we only probe the current mode on startup, we may not have the full

commit f0fd4d500de03c30c7ce19915f85acadd1ca4e5d
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Wed Sep 23 10:52:42 2015 +0100

    sna: Explicitly retire any buffers underneath the static_request
    
    If we are forced to use the static_request (reserved for allocation
    failure), we dispatch the execbuffer synchronously and expect no buffers
    to be present afterwards. Rather than just assert that this is so, we
    should clean up the buffer list!
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index ed1ec58..b975bfc 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3091,7 +3091,6 @@ static bool __kgem_retire_rq(struct kgem *kgem, struct 
kgem_request *rq)
                }
 
                bo->domain = DOMAIN_NONE;
-               bo->gtt_dirty = false;
                bo->rq = NULL;
                if (bo->refcnt)
                        continue;
@@ -3335,6 +3334,7 @@ static void kgem_commit(struct kgem *kgem)
                bo->binding.offset = 0;
                bo->domain = DOMAIN_GPU;
                bo->gpu_dirty = false;
+               bo->gtt_dirty = false;
 
                if (bo->proxy) {
                        /* proxies are not used for domain tracking */
@@ -3358,6 +3358,23 @@ static void kgem_commit(struct kgem *kgem)
                        kgem_throttle(kgem);
                }
 
+               while (!list_is_empty(&rq->buffers)) {
+                       bo = list_first_entry(&rq->buffers,
+                                             struct kgem_bo,
+                                             request);
+
+                       assert(RQ(bo->rq) == rq);
+                       assert(bo->exec == NULL);
+                       assert(bo->domain == DOMAIN_GPU);
+
+                       list_del(&bo->request);
+                       bo->domain = DOMAIN_NONE;
+                       bo->rq = NULL;
+
+                       if (bo->refcnt == 0)
+                               _kgem_bo_destroy(kgem, bo);
+               }
+
                kgem_retire(kgem);
                assert(list_is_empty(&rq->buffers));
 

commit 31d42ed5637a1b2223d48d0db4d7c512b27aee07
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Tue Sep 22 10:23:24 2015 +0100

    sna: Check for udev events before reading
    
    When performing RRGetInfo() we drain any pending uevents before checking
    the CRTC/connector statuses. However, some versions of libudev do a
    blocking read and so when we call RRGetInfo() from a Timer callback
    (outside of the usual sigtimer interrupts) that blocking read lasts
    indefinitely.
    
    Reported-by: Sedat Dilek <sedat.di...@gmail.com>
    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 b57eea4..1b1a125 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4840,6 +4840,8 @@ void sna_mode_discover(struct sna *sna)
        int i, j;
 
        DBG(("%s()\n", __FUNCTION__));
+       sna->flags &= ~SNA_REPROBE;
+
        VG_CLEAR(connectors);
 
        memset(&res, 0, sizeof(res));
@@ -4960,6 +4962,8 @@ static CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 
now, void *data)
                if (output->status == XF86OutputStatusDisconnected)
                        continue;
 
+               DBG(("%s: output %s connected, needs reprobe\n",
+                    __FUNCTION__, output->name));
                reprobe = true;
        }
 
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 18fc48d..539093e 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -755,7 +755,7 @@ sna_handle_uevents(int fd, void *closure)
        if (fstat(sna->kgem.fd, &s))
                memset(&s, 0, sizeof(s));
 
-       do {
+       while (poll(&pfd, 1, 0) > 0) {
                struct udev_device *dev;
                dev_t devnum;
 
@@ -773,7 +773,7 @@ sna_handle_uevents(int fd, void *closure)
                }
 
                udev_device_unref(dev);
-       } while (poll(&pfd, 1, 0) > 0);
+       }
 
        if (hotplug) {
                DBG(("%s: hotplug event (vtSema?=%d)\n",
@@ -890,6 +890,8 @@ sna_randr_getinfo(ScreenPtr screen, Rotation *rotations)
 {
        struct sna *sna = to_sna_from_screen(screen);
 
+       DBG(("%s()\n", __FUNCTION__));
+
        if (!sna_uevent_poll(sna))
                sna_mode_discover(sna);
 
@@ -1221,7 +1223,6 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL)
        if (sna->flags & SNA_REPROBE) {
                DBG(("%s: reporting deferred hotplug event\n", __FUNCTION__));
                sna_mode_discover(sna);
-               sna->flags &= ~SNA_REPROBE;
        }
 
        sna_set_desired_mode(sna);

commit 7be6263b8207b7b7c4a00acf8e2335b345d3fda7
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Fri Sep 18 20:24:29 2015 +0100

    sna: Check alternate userptr mmappings
    
    For a read-only mmaping, we may be able to use a read-write (as we know
    we don't write) if the memory permits us. We can check this by forcing
    the get-user-pages via set-domain(GTT).
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 00378d1..ed1ec58 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -6858,8 +6858,26 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
                             (void *)first_page, last_page-first_page,
                             read_only);
        if (handle == 0) {
-               DBG(("%s: import failed, errno=%d\n", __FUNCTION__, errno));
-               return NULL;
+               if (read_only && kgem->has_wc_mmap) {
+                       struct drm_i915_gem_set_domain set_domain;
+
+                       handle = gem_userptr(kgem->fd,
+                                            (void *)first_page, 
last_page-first_page,
+                                            false);
+
+                       VG_CLEAR(set_domain);
+                       set_domain.handle = handle;
+                       set_domain.read_domains = I915_GEM_DOMAIN_GTT;
+                       set_domain.write_domain = 0;
+                       if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, 
&set_domain)) {
+                               gem_close(kgem->fd, handle);
+                               handle = 0;
+                       }
+               }
+               if (handle == 0) {
+                       DBG(("%s: import failed, errno=%d\n", __FUNCTION__, 
errno));
+                       return NULL;
+               }
        }
 
        bo = __kgem_bo_alloc(handle, (last_page - first_page) / PAGE_SIZE);

commit bbbcc4101ca01a5c8bec5169e47d703dd742494b
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Fri Sep 18 12:17:07 2015 +0100

    sna: Apply cursor hotspot transformation
    
    After applying scaling to the cursor image, it was being positioned on
    the display incorrectly due to the hotspot transformation remaining
    unscaled and so offseting the cursor slightly.
    
    References: https://bugs.archlinux.org/task/45572
    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 332590c..b57eea4 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -169,6 +169,8 @@ struct sna_crtc {
        bool hwcursor;
        bool flip_pending;
 
+       struct pict_f_transform cursor_to_fb, fb_to_cursor;
+
        RegionRec client_damage; /* XXX overlap with shadow damage? */
 
        uint16_t shadow_bo_width, shadow_bo_height;
@@ -5198,36 +5200,6 @@ rotate_coord(Rotation rotation, int size,
        *y_src = y_dst;
 }
 
-static void
-rotate_coord_back(Rotation rotation, int size, int *x, int *y)
-{
-       int t;
-
-       if (rotation & RR_Reflect_X)
-               *x = size - *x - 1;
-       if (rotation & RR_Reflect_Y)
-               *y = size - *y - 1;
-
-       switch (rotation & 0xf) {
-       case RR_Rotate_0:
-               break;
-       case RR_Rotate_90:
-               t = *x;
-               *x = *y;
-               *y = size - t - 1;
-               break;
-       case RR_Rotate_180:
-               *x = size - *x - 1;
-               *y = size - *y - 1;
-               break;
-       case RR_Rotate_270:
-               t = *x;
-               *x = size - *y - 1;
-               *y = t;
-               break;
-       }
-}
-
 static struct sna_cursor *__sna_create_cursor(struct sna *sna, int size)
 {
        struct sna_cursor *c;
@@ -5307,7 +5279,6 @@ static struct sna_cursor *__sna_get_cursor(struct sna 
*sna, xf86CrtcPtr crtc)
        uint32_t *image;
        int width, height, pitch, size, x, y;
        PictTransform cursor_to_fb;
-       struct pict_f_transform f_cursor_to_fb, f_fb_to_cursor;
        bool transformed;
        Rotation rotation;
 
@@ -5365,8 +5336,8 @@ static struct sna_cursor *__sna_get_cursor(struct sna 
*sna, xf86CrtcPtr crtc)
                                   sna->cursor.ref->bits->height,
                                   crtc->rotation, &crtc->transform,
                                   &cursor_to_fb,
-                                  &f_cursor_to_fb,
-                                  &f_fb_to_cursor);
+                                  &to_sna_crtc(crtc)->cursor_to_fb,
+                                  &to_sna_crtc(crtc)->fb_to_cursor);
        } else
                size = sna->cursor.size;
 
@@ -5425,14 +5396,14 @@ static struct sna_cursor *__sna_get_cursor(struct sna 
*sna, xf86CrtcPtr crtc)
                                affine_blt(image, cursor->image, 32,
                                           0, 0, width, height, size * 4,
                                           0, 0, width, height, size * 4,
-                                          &f_cursor_to_fb);
+                                          &to_sna_crtc(crtc)->cursor_to_fb);
                                image = cursor->image;
                        }
                } else if (transformed) {
                        affine_blt(argb, cursor->image, 32,
                                   0, 0, width, height, width * 4,
                                   0, 0, width, height, size * 4,
-                                  &f_cursor_to_fb);
+                                  &to_sna_crtc(crtc)->cursor_to_fb);
                        image = cursor->image;
                } else
                        memcpy_blt(argb, image, 32,
@@ -5743,18 +5714,20 @@ sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
                if (crtc->transform_in_use) {
                        int xhot = sna->cursor.ref->bits->xhot;
                        int yhot = sna->cursor.ref->bits->yhot;
-                       struct pict_f_vector v;
+                       struct pict_f_vector v, hot;
 
                        v.v[0] = (x + xhot) + 0.5;
                        v.v[1] = (y + yhot) + 0.5;
                        v.v[2] = 1;
                        pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, 
&v);
 
-                       rotate_coord_back(crtc->rotation, sna->cursor.size, 
&xhot, &yhot);
+                       hot.v[0] = xhot + .5;
+                       hot.v[1] = yhot + .5;
+                       hot.v[2] = 1.;
+                       pixman_f_transform_point(&sna_crtc->fb_to_cursor, &hot);
 
-                       /* cursor will have 0.5 added to it already so floor is 
sufficient */
-                       arg.x = floor(v.v[0]) - xhot;
-                       arg.y = floor(v.v[1]) - yhot;
+                       arg.x = floor(v.v[0]) - floor(hot.v[0]);
+                       arg.y = floor(v.v[1]) - floor(hot.v[1]);
                } else {
                        arg.x = x - crtc->x;
                        arg.y = y - crtc->y;

commit 15215651a992b7aa06314b9118ad9028b51c7e3e
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Wed Sep 16 13:03:20 2015 +0100

    sna: Refresh last detection timestamp on hotplug notifies
    
    If the status hasn't changed, mark the connector as recently probed.
    
    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 589e2e2..332590c 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4815,11 +4815,14 @@ output_check_status(struct sna *sna, struct sna_output 
*output)
        switch (compat_conn.conn.connection) {
        case DRM_MODE_CONNECTED:
                status = XF86OutputStatusConnected;
+               break;
        case DRM_MODE_DISCONNECTED:
                status = XF86OutputStatusDisconnected;
+               break;
        default:
        case DRM_MODE_UNKNOWNCONNECTION:
                status = XF86OutputStatusUnknown;
+               break;
        }
        return output->status == status;
 }
@@ -4829,7 +4832,7 @@ void sna_mode_discover(struct sna *sna)
        ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
        xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
        struct drm_mode_card_res res;
-       uint32_t connectors[32];
+       uint32_t connectors[32], now;
        unsigned changed = 0;
        unsigned serial;
        int i, j;
@@ -4859,6 +4862,7 @@ void sna_mode_discover(struct sna *sna)
        if (serial == 0)
                serial = ++sna->mode.serial;
 
+       now = GetTimeInMillis();
        for (i = 0; i < res.count_connectors; i++) {
                DBG(("%s: connector[%d] = %d\n", __FUNCTION__, i, 
connectors[i]));
                for (j = 0; j < sna->mode.num_real_output; j++) {
@@ -4884,10 +4888,13 @@ void sna_mode_discover(struct sna *sna)
                        continue;
 
                if (sna_output->serial == serial) {
-                       if (!output_check_status(sna, sna_output)) {
-                               DBG(("%s: output %s (id=%d), changed state, 
reprobing]\n",
-                                    __FUNCTION__, output->name, sna_output->id,
-                                    sna_output->serial, serial));
+                       if (output_check_status(sna, sna_output)) {
+                               DBG(("%s: output %s (id=%d), retained state\n",
+                                    __FUNCTION__, output->name, 
sna_output->id));
+                               sna_output->last_detect = now;
+                       } else {
+                               DBG(("%s: output %s (id=%d), changed state, 
reprobing\n",
+                                    __FUNCTION__, output->name, 
sna_output->id));
                                sna_output->last_detect = 0;
                        }
                        continue;

commit 23986f0a31dbdec2e2086ca898bee43842ab73d4
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Sun Sep 13 20:07:35 2015 +0100

    sna: Update the last known status timestamp on modeset
    
    If the modeset is successful we know the connector is still alive, so
    update its timestamp.
    
    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 9a04419..589e2e2 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -953,6 +953,8 @@ static void
 sna_crtc_force_outputs_on(xf86CrtcPtr crtc)
 {
        xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+       /* All attached outputs are valid, so update our timestamps */
+       unsigned now = GetTimeInMillis();
        int i;
 
        assert(to_sna_crtc(crtc));
@@ -972,6 +974,7 @@ sna_crtc_force_outputs_on(xf86CrtcPtr crtc)
                        continue;
 
                __sna_output_dpms(output, DPMSModeOn, false);
+               to_sna_output(output)->last_detect = now;
        }
 
 #if XF86_CRTC_VERSION >= 3

commit 717b6208d0d7bdcdacaf30b871216e6084c7205c
Author: Chris Wilson <ch...@chris-wilson.co.uk>
Date:   Sun Sep 13 20:06:21 2015 +0100

    sna: Only update the CRTC mode serial number on success
    
    If the kernel doesn't accept the update, then the CRTC remains in its
    previous mode i.e. we should not also touch the modesetting serial
    stamp.
    
    Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c

Reply via email to