diff --git a/src/sna/gen6_common.c b/src/sna/gen6_common.c index 38af859a..8789109f 100644 --- a/src/sna/gen6_common.c +++ b/src/sna/gen6_common.c @@ -69,4 +69,3 @@ void gen6_render_retire(struct kgem *kgem) sna->render.vertex_index = 0; } } - diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 7c0ad119..4c66917b 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -2357,6 +2357,7 @@ static void kgem_commit(struct kgem *kgem) if (!bo->refcnt && !bo->reusable) { assert(!bo->snoop); + assert(!bo->proxy); kgem_bo_free(kgem, bo); continue; } @@ -2451,8 +2452,8 @@ static void kgem_finish_buffers(struct kgem *kgem) if (!DBG_NO_UPLOAD_ACTIVE && used + PAGE_SIZE <= bytes(&bo->base) && (kgem->has_llc || bo->mmapped == MMAPPED_GTT || bo->base.snoop)) { - DBG(("%s: retaining upload buffer (%d/%d)\n", - __FUNCTION__, bo->used, bytes(&bo->base))); + DBG(("%s: retaining upload buffer (%d/%d): used=%d, refcnt=%d\n", + __FUNCTION__, bo->used, bytes(&bo->base), used, bo->base.refcnt)); bo->used = used; if (bo->base.refcnt == 1) { list_move(&bo->base.list, @@ -4634,17 +4635,22 @@ void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) __FUNCTION__, bo->handle, bo->proxy != NULL)); if (bo->proxy) { + assert(!bo->reusable); + kgem_bo_binding_free(kgem, bo); + + assert(list_is_empty(&bo->list)); _list_del(&bo->vma); _list_del(&bo->request); - if (bo->io && bo->exec == NULL && bo->domain == DOMAIN_CPU) - _kgem_bo_delete_buffer(kgem, bo); - kgem_bo_unref(kgem, bo->proxy); - kgem_bo_binding_free(kgem, bo); - free(bo); - return; - } - __kgem_bo_destroy(kgem, bo); + if (bo->io && bo->domain == DOMAIN_CPU) + _kgem_bo_delete_buffer(kgem, bo); + + kgem_bo_unref(kgem, bo->proxy); + + *(struct kgem_bo **)bo = __kgem_freed_bo; + __kgem_freed_bo = bo; + } else + __kgem_bo_destroy(kgem, bo); } static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo) @@ -4993,6 +4999,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem, bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring); bo->exec = &_kgem_dummy_exec; + bo->domain = DOMAIN_GPU; } if (read_write_domain & 0x7fff && !bo->gpu_dirty) @@ -5505,7 +5512,7 @@ struct kgem_bo *kgem_create_proxy(struct kgem *kgem, bo->proxy = kgem_bo_reference(target); bo->delta = offset; - if (target->exec) { + if (target->exec && !bo->io) { list_move_tail(&bo->request, &kgem->next_request->buffers); bo->exec = &_kgem_dummy_exec; } diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 77edfc81..e2bb4f9c 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -370,8 +370,10 @@ static inline void kgem_set_mode(struct kgem *kgem, kgem_submit(kgem); #endif - if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) + if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) { + DBG(("%s: flushing before new bo\n", __FUNCTION__)); _kgem_submit(kgem); + } if (kgem->mode == mode) return; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 7d45065b..93231db9 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -4264,6 +4264,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, DBG(("%s: discarding cached upload proxy\n", __FUNCTION__)); sna_pixmap_free_gpu(sna, priv); } + assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); if (priv->cow || priv->move_to_gpu) { DBG(("%s: no, has COW or pending move-to-gpu\n", __FUNCTION__));