diff -Nru xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/debian/changelog xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/debian/changelog --- xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/debian/changelog 2017-09-28 23:18:30.000000000 +0000 +++ xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/debian/changelog 2017-10-18 20:04:25.000000000 +0000 @@ -1,11 +1,11 @@ -xserver-xorg-video-intel (2:2.99.917+git1709282018.291fdcd~z~padoka0) zesty; urgency=medium +xserver-xorg-video-intel (2:2.99.917+git1710181804.4798e18~z~padoka0) zesty; urgency=medium * Checkout from master git branch up to commit - 291fdcdc09420d8e422617070731eb3da3d55b44 + 4798e18b2b2c8b0a05dc967e6140fd9962bc1a73 * enabled DRI3 by default - -- Paulo Dias Thu, 28 Sep 2017 20:18:30 -0300 + -- Paulo Dias Wed, 18 Oct 2017 18:04:25 -0200 xserver-xorg-video-intel (2:2.99.917+git1412301240.0d42b0e~padoka0) utopic; urgency=medium diff -Nru xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/gen2_render.c xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/gen2_render.c --- xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/gen2_render.c 2017-08-08 00:50:46.000000000 +0000 +++ xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/gen2_render.c 2017-10-18 20:02:52.000000000 +0000 @@ -52,6 +52,7 @@ #define MAX_INLINE (1 << 18) #define BATCH(v) batch_emit(sna, v) +#define BATCH_ALIGNED(v, a) batch_emit_aligned(sna, v, a) #define BATCH_F(v) batch_emit_float(sna, v) #define VERTEX(v) batch_emit_float(sna, v) @@ -568,7 +569,8 @@ { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); - if (!kgem_check_batch(&sna->kgem, INVARIANT_SIZE+40)) { + /* +7 for i830 3DSTATE_BUFFER_INFO w/a */ + if (!kgem_check_batch(&sna->kgem, INVARIANT_SIZE+40+7)) { DBG(("%s: flushing batch: size %d > %d\n", __FUNCTION__, INVARIANT_SIZE+40, sna->kgem.surface-sna->kgem.nbatch)); @@ -614,7 +616,14 @@ return; } - BATCH(_3DSTATE_BUF_INFO_CMD); + /* + * i830 w/a: 3DSTATE_BUFFER_INFO + * must not straddle two cachelines. + */ + if (intel_get_device_id(sna->dev) == 0x3577) + BATCH_ALIGNED(_3DSTATE_BUF_INFO_CMD, 8); + else + BATCH(_3DSTATE_BUF_INFO_CMD); BATCH(BUF_3D_ID_COLOR_BACK | gen2_buf_tiling(bo->tiling) | BUF_3D_PITCH(bo->pitch)); diff -Nru xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/kgem.c xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/kgem.c --- xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/kgem.c 2017-09-28 23:16:36.000000000 +0000 +++ xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/kgem.c 2017-10-18 20:02:52.000000000 +0000 @@ -488,7 +488,7 @@ bo->tiling, tiling, bo->pitch, stride, set_tiling.tiling_mode == tiling)); - return set_tiling.tiling_mode == tiling; + return set_tiling.tiling_mode == tiling && bo->pitch >= stride; } err = errno; @@ -5536,9 +5536,16 @@ if (num_pages(bo) < size) continue; - if (!kgem_set_tiling(kgem, bo, tiling, pitch) && - !exact) + if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { + if (exact) { + DBG(("tiled and pitch not exact: tiling=%d, (want %d), pitch=%d, need %d\n", + bo->tiling, tiling, + bo->pitch, pitch)); + continue; + } + set_gpu_tiling(kgem, bo, tiling, pitch); + } } kgem_bo_remove_from_active(kgem, bo); @@ -5712,9 +5719,16 @@ if (num_pages(bo) < size) continue; - if (!kgem_set_tiling(kgem, bo, tiling, pitch) && - !exact) + if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { + if (exact) { + DBG(("tiled and pitch not exact: tiling=%d, (want %d), pitch=%d, need %d\n", + bo->tiling, tiling, + bo->pitch, pitch)); + continue; + } + set_gpu_tiling(kgem, bo, tiling, pitch); + } } assert(bo->tiling == tiling); assert(bo->pitch >= pitch); diff -Nru xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna_display.c xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna_display.c --- xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna_display.c 2017-09-28 23:16:36.000000000 +0000 +++ xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna_display.c 2017-10-18 20:02:52.000000000 +0000 @@ -192,7 +192,7 @@ }; struct sna_crtc { - unsigned long flags; + struct sna_crtc_public public; uint32_t id; xf86CrtcPtr base; struct drm_mode_modeinfo kmode; @@ -420,7 +420,7 @@ static inline unsigned __sna_crtc_pipe(struct sna_crtc *crtc) { - return crtc->flags >> 8 & 0xff; + return crtc->public.flags >> 8 & 0xff; } static inline unsigned __sna_crtc_id(struct sna_crtc *crtc) @@ -1427,13 +1427,20 @@ static int kmsg_get_debug(void) { - FILE *file; int v = -1; + int fd; - file = fopen("/sys/module/drm/parameters/debug", "r"); - if (file) { - fscanf(file, "%d", &v); - fclose(file); + fd = open("/sys/module/drm/parameters/debug", O_RDONLY); + if (fd != -1) { + char buf[128]; + int len; + + len = read(fd, buf, sizeof(buf) - 1); + if (len != -1) { + buf[len] = '\0'; + v = atoi(buf); + } + close(fd); } return v; @@ -1441,12 +1448,16 @@ static void kmsg_set_debug(int v) { - FILE *file; + char buf[128]; + int len; + int fd; - file = fopen("/sys/module/drm/parameters/debug", "w"); - if (file) { - fprintf(file, "%d\n", v); - fclose(file); + len = snprintf(buf, sizeof(buf), "%d\n", v); + + fd = open("/sys/module/drm/parameters/debug", O_WRONLY); + if (fd != -1) { + write(fd, buf, len); + close(fd); } } @@ -2148,13 +2159,13 @@ if (sna_crtc->bo) { DBG(("%s: releasing handle=%d from scanout, active=%d\n", __FUNCTION__,sna_crtc->bo->handle, sna_crtc->bo->active_scanout-1)); - assert(sna_crtc->flags & CRTC_ON); + assert(sna_crtc->public.flags & CRTC_ON); assert(sna_crtc->bo->active_scanout); assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); sna_crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, sna_crtc->bo); sna_crtc->bo = NULL; - sna_crtc->flags &= ~CRTC_ON; + sna_crtc->public.flags &= ~CRTC_ON; if (sna->mode.hidden) { sna->mode.hidden--; @@ -3089,7 +3100,7 @@ goto error; } - sna_crtc->flags |= CRTC_ON; + sna_crtc->public.flags |= CRTC_ON; bo->active_scanout++; DBG(("%s: marking handle=%d as active=%d (removing %d from scanout, active=%d)\n", __FUNCTION__, bo->handle, bo->active_scanout, @@ -3522,6 +3533,7 @@ if (sna_crtc == NULL) return false; + list_init(&sna_crtc->public.vblank_queue); sna_crtc->id = id; VG_CLEAR(get_pipe); @@ -3534,7 +3546,7 @@ return false; } assert((unsigned)get_pipe.pipe < 256); - sna_crtc->flags |= get_pipe.pipe << 8; + sna_crtc->public.flags |= get_pipe.pipe << 8; if (is_zaphod(scrn) && (get_zaphod_crtcs(sna) & (1 << get_pipe.pipe)) == 0) { @@ -7840,12 +7852,14 @@ __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); if (desired == NULL) { - rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn)); - if (rr && rr->primaryOutput) { + ScreenPtr screen = xf86ScrnToScreen(sna->scrn); + rrScrPrivPtr rr = rrGetScrPriv(screen); + if (rr && rr->primaryOutput && rr->primaryOutput->pScreen == screen) { xf86OutputPtr output = rr->primaryOutput->devPrivate; DBG(("%s: have PrimaryOutput? %d marking as desired\n", __FUNCTION__, output->crtc != NULL)); desired = output->crtc; } + assert(!desired || desired->scrn == sna->scrn); } if (desired && to_sna_crtc(desired) && to_sna_crtc(desired)->bo) { BoxRec cover_box; @@ -7883,8 +7897,9 @@ return crtc; } - if (!sna_box_intersect(&cover_box, &crtc->bounds, box)) - continue; + coverage = 0; + if (sna_box_intersect(&cover_box, &crtc->bounds, box)) + coverage = sna_box_area(&cover_box); DBG(("%s: box instersects (%d, %d), (%d, %d) of crtc %d\n", __FUNCTION__, @@ -7892,7 +7907,6 @@ cover_box.x2, cover_box.y2, c)); - coverage = sna_box_area(&cover_box); DBG(("%s: box covers %d of crtc %d\n", __FUNCTION__, coverage, c)); if (coverage > best_coverage) { diff -Nru xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna.h xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna.h --- xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna.h 2017-08-08 00:50:46.000000000 +0000 +++ xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna.h 2017-10-18 20:02:52.000000000 +0000 @@ -633,16 +633,28 @@ extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx); extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); -#define CRTC_VBLANK 0x3 +#define CRTC_VBLANK 0x7 #define CRTC_ON 0x80000000 uint32_t sna_crtc_id(xf86CrtcPtr crtc); +struct sna_crtc_public { + unsigned long flags; + struct list vblank_queue; +}; + static inline unsigned long *sna_crtc_flags(xf86CrtcPtr crtc) { - unsigned long *flags = crtc->driver_private; - assert(flags); - return flags; + struct sna_crtc_public *pub = crtc->driver_private; + assert(pub); + return &pub->flags; +} + +static inline struct list *sna_crtc_vblank_queue(xf86CrtcPtr crtc) +{ + struct sna_crtc_public *pub = crtc->driver_private; + assert(pub); + return &pub->vblank_queue; } static inline unsigned sna_crtc_pipe(xf86CrtcPtr crtc) @@ -657,12 +669,14 @@ static inline void sna_crtc_set_vblank(xf86CrtcPtr crtc) { - assert((*sna_crtc_flags(crtc) & CRTC_VBLANK) < 3); + DBG(("%s: current vblank count: %d\n", __FUNCTION__, *sna_crtc_flags(crtc) & CRTC_VBLANK)); + assert((*sna_crtc_flags(crtc) & CRTC_VBLANK) < CRTC_VBLANK); ++*sna_crtc_flags(crtc); } static inline void sna_crtc_clear_vblank(xf86CrtcPtr crtc) { + DBG(("%s: current vblank count: %d\n", __FUNCTION__, *sna_crtc_flags(crtc) & CRTC_VBLANK)); assert(*sna_crtc_flags(crtc) & CRTC_VBLANK); --*sna_crtc_flags(crtc); } diff -Nru xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna_present.c xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna_present.c --- xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna_present.c 2017-08-08 00:50:46.000000000 +0000 +++ xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna_present.c 2017-10-18 20:02:52.000000000 +0000 @@ -197,6 +197,16 @@ return MIN(delay, INT32_MAX); } +static void add_to_crtc_vblank(struct sna_present_event *info, + int delta) +{ + info->queued = true; + if (delta == 1 && info->crtc) { + sna_crtc_set_vblank(info->crtc); + info->crtc = mark_crtc(info->crtc); + } +} + static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data) { struct sna_present_event *info = data; @@ -225,11 +235,7 @@ vbl.request.signal = (uintptr_t)MARK_PRESENT(info); if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) { DBG(("%s: scheduled new vblank event for %lld\n", __FUNCTION__, (long long)info->target_msc)); - info->queued = true; - if (delta == 1) { - sna_crtc_set_vblank(info->crtc); - info->crtc = mark_crtc(info->crtc); - } + add_to_crtc_vblank(info, delta); free(timer); return 0; } @@ -326,11 +332,7 @@ if (!sna_fake_vblank(info)) return false; } else { - info->queued = true; - if (delta == 1) { - sna_crtc_set_vblank(info->crtc); - info->crtc = mark_crtc(info->crtc); - } + add_to_crtc_vblank(info, delta); } return true; @@ -360,6 +362,47 @@ return NULL; } +static void add_keepalive(struct sna *sna, xf86CrtcPtr crtc, uint64_t msc) +{ + struct sna_present_event *info, *tmp; + union drm_wait_vblank vbl; + + list_for_each_entry(tmp, sna_crtc_vblank_queue(crtc), link) { + if (tmp->target_msc == msc) { + DBG(("%s: vblank already queued for target_msc=%lld\n", + __FUNCTION__, (long long)msc)); + return; + } + + if ((int64_t)(tmp->target_msc - msc) > 0) + break; + } + + DBG(("%s: adding keepalive for target_msc=%lld\n", + __FUNCTION__, (long long)msc)); + + info = info_alloc(sna); + if (!info) + return; + + info->crtc = crtc; + info->sna = sna; + info->target_msc = msc; + info->event_id = (uint64_t *)(info + 1); + info->n_event_id = 0; + + VG_CLEAR(vbl); + vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; + vbl.request.sequence = msc; + vbl.request.signal = (uintptr_t)MARK_PRESENT(info); + + if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) { + list_add_tail(&info->link, &tmp->link); + add_to_crtc_vblank(info, 1); + } else + info_free(info); +} + static int sna_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc) { @@ -377,34 +420,10 @@ vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc->devPrivate)) == 0) { - struct sna_present_event *info; - *ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec); *msc = sna_crtc_record_vblank(crtc->devPrivate, &vbl); - info = info_alloc(sna); - if (info) { - info->crtc = crtc->devPrivate; - info->sna = sna; - info->target_msc = *msc + 1; - info->event_id = (uint64_t *)(info + 1); - info->n_event_id = 0; - - vbl.request.type = - DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - vbl.request.sequence = info->target_msc; - vbl.request.signal = (uintptr_t)MARK_PRESENT(info); - - if (sna_wait_vblank(info->sna, &vbl, - sna_crtc_pipe(info->crtc)) == 0) { - list_add(&info->link, - &sna->present.vblank_queue); - info->queued = true; - sna_crtc_set_vblank(info->crtc); - info->crtc = mark_crtc(info->crtc); - } else - info_free(info); - } + add_keepalive(sna, crtc->devPrivate, *msc + 1); } else { const struct ust_msc *swap; last: @@ -477,9 +496,8 @@ if (warn_unless(msc - swap->msc < 1ull<<31)) return BadValue; - list_for_each_entry(tmp, &sna->present.vblank_queue, link) { - if (tmp->target_msc == msc && - unmask_crtc(tmp->crtc) == crtc->devPrivate) { + list_for_each_entry(tmp, sna_crtc_vblank_queue(crtc->devPrivate), link) { + if (tmp->target_msc == msc) { uint64_t *events = tmp->event_id; if (tmp->n_event_id && @@ -692,8 +710,10 @@ swap.tv_sec = event->tv_sec; swap.tv_usec = event->tv_usec; swap.msc = event->sequence; - } else + } else { + info->crtc = unmask_crtc(info->crtc); swap = *sna_crtc_last_swap(info->crtc); + } DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld (target %lld), event=%lld complete%s\n", __FUNCTION__, info->crtc ? sna_crtc_pipe(info->crtc) : -1, @@ -702,8 +722,11 @@ (long long)info->event_id[0], info->target_msc && info->target_msc == swap.msc ? "" : ": MISS")); present_event_notify(info->event_id[0], swap_ust(&swap), swap.msc); - if (info->crtc) + if (info->crtc) { sna_crtc_clear_vblank(info->crtc); + if (!sna_crtc_has_vblank(info->crtc)) + add_keepalive(info->sna, info->crtc, swap.msc + 1); + } if (info->sna->present.unflip) { DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, (long long)info->sna->present.unflip)); @@ -747,9 +770,7 @@ return FALSE; } - info->queued = true; - if (info->crtc) - sna_crtc_set_vblank(info->crtc); + add_to_crtc_vblank(info, 1); return TRUE; } diff -Nru xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna_render_inline.h xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna_render_inline.h --- xserver-xorg-video-intel-2.99.917+git1709282018.291fdcd~z~padoka0/src/sna/sna_render_inline.h 2017-08-08 00:50:46.000000000 +0000 +++ xserver-xorg-video-intel-2.99.917+git1710181804.4798e18~z~padoka0/src/sna/sna_render_inline.h 2017-10-18 20:02:52.000000000 +0000 @@ -56,6 +56,15 @@ sna->kgem.batch[sna->kgem.nbatch++] = dword; } +static force_inline void batch_emit_aligned(struct sna *sna, uint32_t dword, unsigned align) +{ + assert(sna->kgem.mode != KGEM_NONE); + assert(sna->kgem.nbatch + KGEM_BATCH_RESERVED < sna->kgem.surface); + while (sna->kgem.nbatch & (align-1)) + sna->kgem.batch[sna->kgem.nbatch++] = 0; + sna->kgem.batch[sna->kgem.nbatch++] = dword; +} + static force_inline void batch_emit64(struct sna *sna, uint64_t qword) { assert(sna->kgem.mode != KGEM_NONE);