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