diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-04-01 22:44:13 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-04-01 23:04:29 +0100 |
commit | 4af622edfc18af523e1fa9063379f68374e19b04 (patch) | |
tree | 2164e8d4088168d509d879293e6e01bace54b6d8 | |
parent | ef0038d358e613381e03c077e06a87fc49108d87 (diff) |
sna: Try to eliminate pending operations to the bo being replaced
When we are replacing a bo with fresh data, we can drop pending
operations to it and thereby reduce the complexity of the replacement.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 29 | ||||
-rw-r--r-- | src/sna/kgem.h | 2 | ||||
-rw-r--r-- | src/sna/sna_io.c | 25 |
3 files changed, 27 insertions, 29 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 231dc8e7..9013e68c 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1732,6 +1732,23 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags) return NULL; } +void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo) +{ + if (kgem->nexec != 1 || bo->exec == NULL) + return; + + DBG(("%s: only handle in batch, discarding last operations\n", + __FUNCTION__)); + + assert(bo->exec == &kgem->exec[0]); + assert(kgem->exec[0].handle == bo->handle); + assert(RQ(bo->rq) == kgem->next_request); + + bo->refcnt++; + kgem_reset(kgem); + bo->refcnt--; +} + static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); @@ -1782,16 +1799,8 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) assert(bo->io == false); assert(bo->scanout == false); - if (bo->exec && kgem->nexec == 1) { - DBG(("%s: only handle in batch, discarding last operations\n", - __FUNCTION__)); - assert(bo->exec == &kgem->exec[0]); - assert(kgem->exec[0].handle == bo->handle); - assert(RQ(bo->rq) == kgem->next_request); - bo->refcnt = 1; - kgem_reset(kgem); - bo->refcnt = 0; - } + kgem_bo_undo(kgem, bo); + assert(bo->refcnt == 0); if (bo->rq && bo->exec == NULL && !__kgem_busy(kgem, bo->handle)) __kgem_bo_clear_busy(bo); diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 82f9b522..f2b1c980 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -573,6 +573,8 @@ static inline bool kgem_bo_is_snoop(struct kgem_bo *bo) return bo->snoop; } +void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo); + bool __kgem_busy(struct kgem *kgem, int handle); static inline void kgem_bo_mark_busy(struct kgem_bo *bo, int ring) diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index 540f3a60..14c0d8c7 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -1362,38 +1362,25 @@ bool sna_replace(struct sna *sna, { struct kgem_bo *bo = *_bo; struct kgem *kgem = &sna->kgem; - bool busy; void *dst; - busy = __kgem_bo_is_busy(kgem, bo); DBG(("%s(handle=%d, %dx%d, bpp=%d, tiling=%d) busy?=%d\n", __FUNCTION__, bo->handle, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, - bo->tiling, busy)); + bo->tiling, + __kgem_bo_is_busy(kgem, bo))); assert(!sna_pixmap(pixmap)->pinned); - if (!busy && upload_inplace__tiled(kgem, bo)) { - BoxRec box; + kgem_bo_undo(kgem, bo); - box.x1 = box.y1 = 0; - box.x2 = pixmap->drawable.width; - box.y2 = pixmap->drawable.height; + if (__kgem_bo_is_busy(kgem, bo)) { + struct kgem_bo *new_bo; - if (write_boxes_inplace__tiled(kgem, src, - stride, pixmap->drawable.bitsPerPixel, 0, 0, - bo, 0, 0, &box, 1)) + if (indirect_replace(sna, pixmap, bo, src, stride)) return true; - } - - if ((busy || !kgem_bo_can_map(kgem, bo)) && - indirect_replace(sna, pixmap, bo, src, stride)) - return true; - - if (busy) { - struct kgem_bo *new_bo; new_bo = kgem_create_2d(kgem, pixmap->drawable.width, |