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, ®ion, 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, ®ion, dst, flags)) + return; + if (!sna_drawable_move_region_to_cpu(drawable, ®ion, 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, + ®ion->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