Makefile.am | 2 NEWS | 32 +++ configure.ac | 7 m4/ac_define_dir.m4 | 49 ++++ src/intel_dri.c | 15 + src/intel_driver.h | 51 +++- src/intel_module.c | 99 +++++++-- src/sna/Makefile.am | 2 src/sna/compiler.h | 2 src/sna/gen4_render.c | 10 src/sna/gen4_vertex.c | 6 src/sna/gen5_render.c | 7 src/sna/gen6_render.c | 2 src/sna/gen7_render.c | 31 ++ src/sna/kgem.c | 144 ++++++++++--- src/sna/kgem.h | 9 src/sna/sna.h | 18 + src/sna/sna_accel.c | 445 +++++++++++++++++++++++++++++++++++++------ src/sna/sna_blt.c | 46 +++- src/sna/sna_composite.c | 20 + src/sna/sna_display.c | 23 +- src/sna/sna_dri.c | 27 ++ src/sna/sna_driver.c | 23 +- src/sna/sna_render.c | 13 - src/sna/sna_trapezoids.c | 85 +++++--- src/sna/sna_video.c | 10 src/sna/sna_video.h | 19 + src/sna/sna_video_hwmc.c | 75 +++---- src/sna/sna_video_hwmc.h | 4 src/sna/sna_video_overlay.c | 53 +++-- src/sna/sna_video_sprite.c | 46 +++- src/sna/sna_video_textured.c | 57 ----- 32 files changed, 1087 insertions(+), 345 deletions(-)
New commits: commit e65ee10dfd7155230ac18a6d24a67b68336dc973 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Tue May 21 11:01:50 2013 +0100 2.21.7 release diff --git a/NEWS b/NEWS index 4fc9a6b..3173f21 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,35 @@ +Release 2.21.7 (2013-05-21) +=========================== +A couple of weeks turned into a month and a couple of weeks... Amidst +the usual bug fixes, we have added the complete set of Haswell PCI IDs - +hopefully future proofing ourselves against being surprised by new +products. We can also now use the correct term for the top of the range +Haswell variants, GT3. + + * Fix several assertion failures hit by Jiri Slaby. + + * Allow XvMC to also target overlay/sprite planes. + + * Throw in a paranoid MI_FLUSH between BLT and RENDER operations on + Ironlake. + https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1168066 + + * Prevent reuse of old framebuffers after a resize. + https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1157678 + + * Fix compilation with --enable-valgrind and no --enable-debug + + * Improve partial migration of render sources. + + * Fix origin of trapezoids. + https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1178020 + + * Introduce copy-on-write support for cloning pixmaps. The ultimate + goal here is to efficiently support the TearFree mode of operation, + but this provides immediate benefits with firefox - most importantly + because of the inefficient way it now implements scrolling. + + Release 2.21.6 (2013-04-06) =========================== A surprising highlight of this release is a little refresh to the KMS diff --git a/configure.ac b/configure.ac index d30686f..be1e8d1 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-intel], - [2.21.6], + [2.21.7], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-intel]) AC_CONFIG_SRCDIR([Makefile.am]) commit ef9dc6fae585d5616446eedc1e6e91173f4064c1 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Mon May 20 11:08:51 2013 +0100 sna: Undo a few more overwritten operations upon a bo Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna.h b/src/sna/sna.h index aed3e08..ee3f821 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -507,6 +507,7 @@ struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling); #define FORCE_GPU 0x2 #define RENDER_GPU 0x4 #define IGNORE_CPU 0x8 +#define REPLACES 0x10 struct kgem_bo * sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, struct sna_damage ***damage); diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 2c78570..6ed9e77 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -2946,6 +2946,8 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, box->x1, box->y1, box->x2, box->y2, flags)); + assert((hint & REPLACES) == 0 || (hint & IGNORE_CPU)); + assert(box->x2 > box->x1 && box->y2 > box->y1); assert(pixmap->refcnt); assert_pixmap_damage(pixmap); @@ -3001,7 +3003,7 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, __FUNCTION__, priv->flush, priv->shm, priv->cpu, flags)); if ((flags & PREFER_GPU) == 0 && - (!priv->gpu_damage || !kgem_bo_is_busy(priv->gpu_bo))) { + (flags & REPLACES || !priv->gpu_damage || !kgem_bo_is_busy(priv->gpu_bo))) { DBG(("%s: try cpu as GPU bo is idle\n", __FUNCTION__)); goto use_cpu_bo; } @@ -12179,18 +12181,20 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) } hint |= IGNORE_CPU; } - if (priv->cpu_damage == NULL && - (region_subsumes_drawable(®ion, &pixmap->drawable) || - box_inplace(pixmap, ®ion.extents))) { - DBG(("%s: promoting to full GPU\n", __FUNCTION__)); - if (priv->gpu_bo) { - assert(priv->gpu_bo->proxy == NULL); - sna_damage_all(&priv->gpu_damage, - pixmap->drawable.width, - pixmap->drawable.height); - } - } + if (region_subsumes_drawable(®ion, &pixmap->drawable)) + hint |= REPLACES; if (priv->cpu_damage == NULL) { + if (hint & REPLACES && + box_inplace(pixmap, ®ion.extents)) { + DBG(("%s: promoting to full GPU\n", + __FUNCTION__)); + if (priv->gpu_bo) { + assert(priv->gpu_bo->proxy == NULL); + sna_damage_all(&priv->gpu_damage, + pixmap->drawable.width, + pixmap->drawable.height); + } + } DBG(("%s: dropping last-cpu hint\n", __FUNCTION__)); priv->cpu = false; } @@ -12209,6 +12213,8 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) DBG(("%s: not using GPU, hint=%x\n", __FUNCTION__, hint)); goto fallback; } + if (hint & REPLACES) + kgem_bo_undo(&sna->kgem, bo); if (gc_is_solid(gc, &color)) { DBG(("%s: solid fill [%08x], testing for blt\n", diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index ae63e68..17cc68c 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -933,8 +933,9 @@ sna_composite_rectangles(CARD8 op, sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); } - if (region_subsumes_drawable(®ion, &pixmap->drawable) || - box_inplace(pixmap, ®ion.extents)) { + if (region_subsumes_drawable(®ion, &pixmap->drawable)) + hint |= REPLACES; + if (hint & REPLACES || box_inplace(pixmap, ®ion.extents)) { DBG(("%s: promoting to full GPU\n", __FUNCTION__)); if (priv->gpu_bo && priv->cpu_damage == NULL) { assert(priv->gpu_bo->proxy == NULL); @@ -958,6 +959,8 @@ sna_composite_rectangles(CARD8 op, DBG(("%s: fallback due to no GPU bo\n", __FUNCTION__)); goto fallback; } + if (hint & REPLACES) + kgem_bo_undo(&sna->kgem, bo); if (!sna->render.fill_boxes(sna, op, dst->format, color, pixmap, bo, boxes, num_boxes)) { commit d6c30d1d4df6bcdfa075bd29da7c8aabee20774c Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Fri May 17 12:11:34 2013 +0100 sna: Clear the cow_list when discarding the clone upon pixmap destroy 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 a50f4d4..2c78570 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1366,6 +1366,10 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap) if (priv->cow) { struct sna_cow *cow = COW(priv->cow); + DBG(("%s: pixmap=%ld discarding cow, refcnt=%d\n", + __FUNCTION__, pixmap->drawable.serialNumber, cow->refcnt)); + assert(cow->refcnt); + list_del(&priv->cow_list); if (!--cow->refcnt) free(cow); priv->cow = NULL; @@ -1556,8 +1560,9 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) list_del(&priv->cow_list); if (!--cow->refcnt) { + assert(list_is_empty(&cow->list)); free(cow); - } else if (IS_COW_OWNER(priv->cow)) { + } else if (IS_COW_OWNER(priv->cow) && priv->pinned) { PixmapPtr pixmap = priv->pixmap; struct kgem_bo *bo; BoxRec box; @@ -1589,7 +1594,6 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) return false; } - cow->bo = bo; assert(!list_is_empty(&cow->list)); while (!list_is_empty(&cow->list)) { struct sna_pixmap *clone; @@ -1598,9 +1602,11 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) struct sna_pixmap, cow_list); list_del(&clone->cow_list); + assert(clone->gpu_bo == cow->bo); kgem_bo_destroy(&sna->kgem, clone->gpu_bo); clone->gpu_bo = kgem_bo_reference(bo); } + cow->bo = bo; kgem_bo_destroy(&sna->kgem, bo); } else { struct kgem_bo *bo = NULL; @@ -1681,6 +1687,9 @@ sna_pixmap_make_cow(struct sna *sna, cow->bo = src_priv->gpu_bo; cow->refcnt = 1; + DBG(("%s: attaching source cow to pixmap=%ld\n", + __FUNCTION__, src_priv->pixmap->drawable.serialNumber)); + src_priv->cow = MAKE_COW_OWNER(cow); list_init(&src_priv->cow_list); @@ -1691,8 +1700,10 @@ sna_pixmap_make_cow(struct sna *sna, } assert(!src_priv->mapped); - if (cow == COW(dst_priv->cow)) + if (cow == COW(dst_priv->cow)) { + assert(dst_priv->gpu_bo == cow->bo); return true; + } if (dst_priv->cow) sna_pixmap_undo_cow(sna, dst_priv, 0); @@ -1704,6 +1715,9 @@ sna_pixmap_make_cow(struct sna *sna, list_add(&dst_priv->cow_list, &cow->list); cow->refcnt++; + DBG(("%s: attaching clone to pixmap=%ld\n", + __FUNCTION__, dst_priv->pixmap->drawable.serialNumber)); + if (dst_priv->mapped) { dst_priv->pixmap->devPrivate.ptr = NULL; dst_priv->mapped = false; commit 21f17455650d52848467290f609c678e85b8ceab Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Fri May 17 11:46:16 2013 +0100 sna: Add the missing ref(bo) when undoing the source clone 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 7e3c0bb..a50f4d4 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1599,7 +1599,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) list_del(&clone->cow_list); kgem_bo_destroy(&sna->kgem, clone->gpu_bo); - clone->gpu_bo = bo; + clone->gpu_bo = kgem_bo_reference(bo); } kgem_bo_destroy(&sna->kgem, bo); } else { commit ee166ca856ac02ca8900b9ff44ed3899add2c72a Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Fri May 17 11:30:03 2013 +0100 sna: Undo the clone when replacing the DRI pixmap Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna.h b/src/sna/sna.h index c8a954d..aed3e08 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -451,6 +451,9 @@ PixmapPtr sna_pixmap_create_unattached(ScreenPtr screen, int width, int height, int depth); void sna_pixmap_destroy(PixmapPtr pixmap); +bool +sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags); + #define MOVE_WRITE 0x1 #define MOVE_READ 0x2 #define MOVE_INPLACE_HINT 0x4 diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index b3dca97..7e3c0bb 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1538,7 +1538,7 @@ static inline bool use_cpu_bo_for_upload(struct sna *sna, return kgem_bo_is_busy(priv->gpu_bo) || kgem_bo_is_busy(priv->cpu_bo); } -static bool +bool sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { struct sna_cow *cow = COW(priv->cow); diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 99f9d12..06d1f21 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -505,11 +505,13 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) assert(pixmap->drawable.height * bo->pitch <= kgem_bo_size(bo)); assert(bo->proxy == NULL); assert(bo->flush); - assert(priv->cow == NULL); assert(priv->pinned & PIN_DRI); assert((priv->pinned & PIN_PRIME) == 0); assert(priv->flush); + if (priv->cow) + sna_pixmap_undo_cow(sna, priv, 0); + /* Post damage on the new front buffer so that listeners, such * as DisplayLink know take a copy and shove it over the USB, * also for software cursors and the like. @@ -529,7 +531,8 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) assert(bo->refcnt); if (priv->gpu_bo != bo) { - kgem_bo_destroy(&sna->kgem, priv->gpu_bo); + if (priv->gpu_bo) + kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = ref(bo); if (priv->mapped) { assert(!priv->shm && priv->stride); commit 8d31fe771b423a3768cbd05db994d49e941369e1 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Fri May 17 11:14:34 2013 +0100 sna: Transfer ownership of the cloned bo to the pixmaps Fix the leak from the previous commit. 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 1dd8491..b3dca97 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1590,6 +1590,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) } cow->bo = bo; + assert(!list_is_empty(&cow->list)); while (!list_is_empty(&cow->list)) { struct sna_pixmap *clone; @@ -1600,6 +1601,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) kgem_bo_destroy(&sna->kgem, clone->gpu_bo); clone->gpu_bo = bo; } + kgem_bo_destroy(&sna->kgem, bo); } else { struct kgem_bo *bo = NULL; commit 5d9315873e02d4acc5ddffc698dbf8984cbd5c42 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Fri May 17 10:51:44 2013 +0100 sna: Avoid replacing pinned bo when undoing a clone Otherwise we end up cloning the scanout only to leave it dangling if the client copies the from the front-buffer and then writes to it. Reported-by: Nick Bowler <nbow...@draconx.ca> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=64675 Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/sna.h b/src/sna/sna.h index e381ce4..c8a954d 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -108,6 +108,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. struct sna_cow { struct kgem_bo *bo; + struct list list; int refcnt; }; @@ -119,7 +120,8 @@ struct sna_pixmap { void *ptr; #define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1)) - struct list list; + struct list flush_list; + struct list cow_list; uint32_t stride; uint32_t clear_color; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 8125455..1dd8491 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -101,6 +101,10 @@ #define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1) #define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1)) +#define IS_COW_OWNER(ptr) ((uintptr_t)(ptr) & 1) +#define MAKE_COW_OWNER(ptr) ((void*)((uintptr_t)(ptr) | 1)) +#define COW(ptr) (void *)((uintptr_t)(ptr) & ~1) + #if 0 static void __sna_fallback_flush(DrawablePtr d) { @@ -513,7 +517,7 @@ static void __sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv) static void sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv) { assert(priv->cpu_damage == NULL); - assert(list_is_empty(&priv->list)); + assert(list_is_empty(&priv->flush_list)); if (IS_STATIC_PTR(priv->ptr)) return; @@ -653,7 +657,7 @@ static inline void sna_set_pixmap(PixmapPtr pixmap, struct sna_pixmap *sna) static struct sna_pixmap * _sna_pixmap_init(struct sna_pixmap *priv, PixmapPtr pixmap) { - list_init(&priv->list); + list_init(&priv->flush_list); priv->source_count = SOURCE_BIAS; priv->pixmap = pixmap; @@ -1304,7 +1308,7 @@ void sna_add_flush_pixmap(struct sna *sna, assert(bo); assert(bo->flush); assert(priv->gpu_damage == NULL || priv->gpu_bo); - list_move(&priv->list, &sna->flush_pixmaps); + list_move(&priv->flush_list, &sna->flush_pixmaps); if (bo->exec == NULL && kgem_is_idle(&sna->kgem)) { DBG(("%s: new flush bo, flushin before\n", __FUNCTION__)); @@ -1316,7 +1320,7 @@ static void __sna_free_pixmap(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv) { - list_del(&priv->list); + list_del(&priv->flush_list); assert(priv->gpu_damage == NULL); assert(priv->cpu_damage == NULL); @@ -1361,8 +1365,9 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap) sna_damage_destroy(&priv->cpu_damage); if (priv->cow) { - if (!--priv->cow->refcnt) - free(priv->cow); + struct sna_cow *cow = COW(priv->cow); + if (!--cow->refcnt) + free(cow); priv->cow = NULL; } @@ -1536,17 +1541,65 @@ static inline bool use_cpu_bo_for_upload(struct sna *sna, static bool sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { + struct sna_cow *cow = COW(priv->cow); + DBG(("%s: pixmap=%ld, handle=%ld, flags=%x\n", __FUNCTION__, priv->pixmap->drawable.serialNumber, priv->gpu_bo->handle, flags)); - assert(priv->gpu_bo == priv->cow->bo); + assert(priv->gpu_bo == cow->bo); assert(!priv->mapped); + assert(cow->refcnt); + + list_del(&priv->cow_list); + + if (!--cow->refcnt) { + free(cow); + } else if (IS_COW_OWNER(priv->cow)) { + PixmapPtr pixmap = priv->pixmap; + struct kgem_bo *bo; + BoxRec box; + + DBG(("%s: copying the Holy cow\n", __FUNCTION__)); + + box.x1 = box.y1 = 0; + box.x2 = pixmap->drawable.width; + box.y2 = pixmap->drawable.height; - if (!--priv->cow->refcnt) { - free(priv->cow); + bo = kgem_create_2d(&sna->kgem, + box.x2, box.y2, + pixmap->drawable.bitsPerPixel, + sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING), + 0); + if (bo == NULL) { + cow->refcnt++; + DBG(("%s: allocation failed\n", __FUNCTION__)); + return false; + } + + if (!sna->render.copy_boxes(sna, GXcopy, + pixmap, priv->gpu_bo, 0, 0, + pixmap, bo, 0, 0, + &box, 1, 0)) { + DBG(("%s: copy failed\n", __FUNCTION__)); + kgem_bo_destroy(&sna->kgem, bo); + cow->refcnt++; + return false; + } + + cow->bo = bo; + while (!list_is_empty(&cow->list)) { + struct sna_pixmap *clone; + + clone = list_first_entry(&cow->list, + struct sna_pixmap, cow_list); + list_del(&clone->cow_list); + + kgem_bo_destroy(&sna->kgem, clone->gpu_bo); + clone->gpu_bo = bo; + } } else { struct kgem_bo *bo = NULL; @@ -1566,7 +1619,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING), 0); if (bo == NULL) { - priv->cow->refcnt++; + cow->refcnt++; DBG(("%s: allocation failed\n", __FUNCTION__)); return false; } @@ -1577,7 +1630,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) &box, 1, 0)) { DBG(("%s: copy failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, bo); - priv->cow->refcnt++; + cow->refcnt++; return false; } } @@ -1607,25 +1660,27 @@ sna_pixmap_make_cow(struct sna *sna, dst_priv->pixmap->drawable.serialNumber, src_priv->gpu_bo->handle)); - if (src_priv->pinned & PIN_DRI || dst_priv->pinned) { - DBG(("%s: can't cow, src pinned=%x, dst_pinned=%x\n", - __FUNCTION__, src_priv->pinned, dst_priv->pinned)); + if (dst_priv->pinned) { + DBG(("%s: can't cow, dst_pinned=%x\n", + __FUNCTION__, dst_priv->pinned)); return false; } - assert(!src_priv->flush); assert(!dst_priv->flush); - cow = src_priv->cow; + cow = COW(src_priv->cow); if (cow == NULL) { cow = malloc(sizeof(*cow)); if (cow == NULL) return false; + list_init(&cow->list); + cow->bo = src_priv->gpu_bo; cow->refcnt = 1; - src_priv->cow = cow; + src_priv->cow = MAKE_COW_OWNER(cow); + list_init(&src_priv->cow_list); if (src_priv->mapped) { src_priv->pixmap->devPrivate.ptr = NULL; @@ -1634,7 +1689,7 @@ sna_pixmap_make_cow(struct sna *sna, } assert(!src_priv->mapped); - if (cow == dst_priv->cow) + if (cow == COW(dst_priv->cow)) return true; if (dst_priv->cow) @@ -1644,6 +1699,7 @@ sna_pixmap_make_cow(struct sna *sna, kgem_bo_destroy(&sna->kgem, dst_priv->gpu_bo); dst_priv->gpu_bo = kgem_bo_reference(cow->bo); dst_priv->cow = cow; + list_add(&dst_priv->cow_list, &cow->list); cow->refcnt++; if (dst_priv->mapped) { @@ -1742,7 +1798,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags) sna_damage_destroy(&priv->cpu_damage); priv->clear = false; priv->cpu = false; - list_del(&priv->list); + list_del(&priv->flush_list); assert(!priv->shm); assert(priv->cpu_bo == NULL || !priv->cpu_bo->flush); @@ -1800,7 +1856,7 @@ skip_inplace_map: pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); sna_pixmap_free_cpu(sna, priv); - list_del(&priv->list); + list_del(&priv->flush_list); priv->clear = false; } priv->cpu = false; @@ -1839,7 +1895,7 @@ skip_inplace_map: pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); sna_pixmap_free_cpu(sna, priv); - list_del(&priv->list); + list_del(&priv->flush_list); priv->clear = false; } @@ -2184,7 +2240,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, __FUNCTION__)); assert(priv->cpu == false || (priv->mapped && IS_CPU_MAP(priv->gpu_bo->map))); sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); } else sna_damage_subtract(&priv->cpu_damage, region); @@ -2505,7 +2561,7 @@ out: priv->source_count = SOURCE_BIAS; assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); assert(priv->gpu_bo || priv->gpu_damage == NULL); - assert(!priv->flush || !list_is_empty(&priv->list)); + assert(!priv->flush || !list_is_empty(&priv->flush_list)); } if ((flags & MOVE_ASYNC_HINT) == 0 && priv->cpu_bo) { DBG(("%s: syncing cpu bo\n", __FUNCTION__)); @@ -2663,7 +2719,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl assert(priv->gpu_bo->proxy == NULL); assert(priv->cpu == false || (priv->mapped && IS_CPU_MAP(priv->gpu_bo->map))); sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); goto done; } @@ -2682,7 +2738,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl assert_pixmap_damage(pixmap); if (priv->cpu_damage == NULL) { - list_del(&priv->list); + list_del(&priv->flush_list); return sna_pixmap_move_to_gpu(pixmap, flags); } @@ -2851,7 +2907,7 @@ done: sna_pixmap_free_cpu(sna, priv); } if (priv->cpu_damage == NULL && priv->flush) - list_del(&priv->list); + list_del(&priv->flush_list); assert(!priv->gpu_bo->proxy || (flags & MOVE_WRITE) == 0); return sna_pixmap_mark_active(sna, priv) != NULL; @@ -3012,7 +3068,7 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, sna_damage_subtract(&priv->cpu_damage, ®ion); if (priv->cpu_damage == NULL) { - list_del(&priv->list); + list_del(&priv->flush_list); priv->cpu = false; } } @@ -3105,7 +3161,7 @@ done: pixmap->drawable.width, pixmap->drawable.height)) { sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); *damage = NULL; } else *damage = &priv->gpu_damage; @@ -3357,7 +3413,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) assert(priv->gpu_bo->proxy == NULL); assert(priv->cpu == false || (priv->mapped && IS_CPU_MAP(priv->gpu_bo->map))); sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); goto active; } @@ -3508,7 +3564,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) sna_pixmap_free_cpu(sna, priv); } done: - list_del(&priv->list); + list_del(&priv->flush_list); sna_damage_reduce_all(&priv->gpu_damage, pixmap->drawable.width, @@ -4545,7 +4601,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, dst_priv->gpu_bo = NULL; } sna_damage_destroy(&dst_priv->cpu_damage); - list_del(&dst_priv->list); + list_del(&dst_priv->flush_list); dst_priv->cpu = false; } if (region->data == NULL) @@ -4619,7 +4675,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, dst_pixmap->drawable.width, dst_pixmap->drawable.height); sna_damage_destroy(&dst_priv->cpu_damage); - list_del(&dst_priv->list); + list_del(&dst_priv->flush_list); if (dst_priv->shm) sna_add_flush_pixmap(sna, dst_priv, dst_priv->cpu_bo); return; @@ -4866,7 +4922,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, sna_damage_all(&dst_priv->gpu_damage, dst_pixmap->drawable.width, dst_pixmap->drawable.height); - list_del(&dst_priv->list); + list_del(&dst_priv->flush_list); } else sna_damage_add(&dst_priv->gpu_damage, region); @@ -9652,7 +9708,7 @@ sna_poly_fill_rect_blt(DrawablePtr drawable, pixmap->drawable.width, pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); priv->clear = true; priv->clear_color = gc->alu == GXcopy ? pixel : 0; @@ -12103,7 +12159,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) priv->gpu_bo = NULL; } sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); } hint |= IGNORE_CPU; } @@ -13965,9 +14021,9 @@ sna_accel_flush_callback(CallbackListPtr *list, bool ret; priv = list_first_entry(&sna->flush_pixmaps, - struct sna_pixmap, list); + struct sna_pixmap, flush_list); - list_del(&priv->list); + list_del(&priv->flush_list); if (priv->shm) { DBG(("%s: syncing SHM pixmap=%ld (refcnt=%d)\n", __FUNCTION__, diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index df2aa1a..ae63e68 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -627,7 +627,7 @@ sna_composite(CARD8 op, sna_damage_subtract(&priv->cpu_damage, ®ion); if (priv->cpu_damage == NULL) { - list_del(&priv->list); + list_del(&priv->flush_list); priv->cpu = false; } @@ -931,7 +931,7 @@ sna_composite_rectangles(CARD8 op, priv->gpu_bo = NULL; } sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); } if (region_subsumes_drawable(®ion, &pixmap->drawable) || box_inplace(pixmap, ®ion.extents)) { diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 77b2e07..99f9d12 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -443,7 +443,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer) pixmap->drawable.serialNumber, pixmap == sna->front)); - list_del(&priv->list); + list_del(&priv->flush_list); priv->gpu_bo->flush = false; priv->pinned &= ~PIN_DRI; @@ -524,7 +524,7 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) pixmap->drawable.width, pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); - list_del(&priv->list); + list_del(&priv->flush_list); priv->cpu = false; assert(bo->refcnt); diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c index 7907e8d..5af7d41 100644 --- a/src/sna/sna_trapezoids.c +++ b/src/sna/sna_trapezoids.c @@ -6712,7 +6712,7 @@ static void mark_damaged(PixmapPtr pixmap, struct sna_pixmap *priv, sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); - list_del(&priv->list); + list_del(&priv->flush_list); } else { sna_damage_add_box(&priv->gpu_damage, box); sna_damage_subtract_box(&priv->cpu_damage, box); commit 3efe143e367acfa2ff38c63388d24a8d06331944 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Fri May 17 10:30:51 2013 +0100 sna: Clear mapped hints upon cloning a pair of pixmaps Once cloned, we do not want to use inplace operations and instead force a copy. However, if we do not relinquish the hints when copying across the bo, then those hints become stale and lead to corruption. 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 f6246a3..8125455 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1536,14 +1536,15 @@ static inline bool use_cpu_bo_for_upload(struct sna *sna, static bool sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { - assert(priv->gpu_bo == priv->cow->bo); - DBG(("%s: pixmap=%ld, handle=%ld, flags=%x\n", __FUNCTION__, priv->pixmap->drawable.serialNumber, priv->gpu_bo->handle, flags)); + assert(priv->gpu_bo == priv->cow->bo); + assert(!priv->mapped); + if (!--priv->cow->refcnt) { free(priv->cow); } else { @@ -1612,6 +1613,7 @@ sna_pixmap_make_cow(struct sna *sna, return false; } + assert(!src_priv->flush); assert(!dst_priv->flush); cow = src_priv->cow; @@ -1624,7 +1626,13 @@ sna_pixmap_make_cow(struct sna *sna, cow->refcnt = 1; src_priv->cow = cow; + + if (src_priv->mapped) { + src_priv->pixmap->devPrivate.ptr = NULL; + src_priv->mapped = false; + } } + assert(!src_priv->mapped); if (cow == dst_priv->cow) return true; @@ -1638,6 +1646,11 @@ sna_pixmap_make_cow(struct sna *sna, dst_priv->cow = cow; cow->refcnt++; + if (dst_priv->mapped) { + dst_priv->pixmap->devPrivate.ptr = NULL; + dst_priv->mapped = false; + } + return true; } commit f57a65c35268f215c17f1a02b3af50a6678ce3c1 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Tue May 14 16:15:57 2013 +0100 sna: Correct assertions to allow discarding of cpu hint for inplace ops Reported-by: Zdenek Kabelac <zkabe...@redhat.com> 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 067e2dd..f6246a3 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1711,6 +1711,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags) DBG(("%s: write inplace\n", __FUNCTION__)); assert(!priv->shm); assert(priv->gpu_bo->exec == NULL); + assert((flags & MOVE_READ) == 0 || priv->cpu_damage == NULL); pixmap->devPrivate.ptr = kgem_bo_map(&sna->kgem, priv->gpu_bo); @@ -1769,7 +1770,7 @@ skip_inplace_map: pixmap_inplace(sna, pixmap, priv, (flags & MOVE_READ) == 0) && sna_pixmap_create_mappable_gpu(pixmap, (flags & MOVE_READ) == 0)) { DBG(("%s: try to operate inplace (GTT)\n", __FUNCTION__)); - assert((flags & MOVE_READ) == 0 || priv->cpu == false); + assert((flags & MOVE_READ) == 0 || priv->cpu_damage == NULL); /* XXX only sync for writes? */ kgem_bo_submit(&sna->kgem, priv->gpu_bo); assert(priv->gpu_bo->exec == NULL); commit bb0969e6a5c2bddcd0499d81c0c241003f8b07ef Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Tue May 14 15:22:59 2013 +0100 sna: Assert that the mapping is released before closing the GEM handle Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 8b096c5..ef8f036 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1499,6 +1499,7 @@ static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo) if (bo->map) kgem_bo_release_map(kgem, bo); assert(list_is_empty(&bo->vma)); + assert(bo->map == NULL); _list_del(&bo->list); _list_del(&bo->request); @@ -2182,6 +2183,7 @@ static void kgem_commit(struct kgem *kgem) kgem_retire(kgem); assert(list_is_empty(&rq->buffers)); + assert(rq->bo->map == NULL); gem_close(kgem->fd, rq->bo->handle); kgem_cleanup_cache(kgem); } else { @@ -5796,7 +5798,7 @@ kgem_replace_bo(struct kgem *kgem, return NULL; dst = __kgem_bo_alloc(handle, size); -- 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/e1ufqed-0006kv...@vasks.debian.org